Properties
PropTypes
Json
static propTypes = {
link: React.PropTypes.shape({
description: React.PropTypes.string.isRequired,
url: React.PropTypes.string.isRequired,
id: React.PropTypes.string.isRequired,
}),
};
Array
static propTypes = {
links: React.PropTypes.arrayOf(React.PropTypes.shape({
description: React.PropTypes.string.isRequired,
url: React.PropTypes.string.isRequired,
id: React.PropTypes.string.isRequired,
})),
};
Handle Click
onDoorListRowClick(cell, row, rowIndex) {
console.log('clicked', cell, row, rowIndex);
}
// OR
onDoorListRowClick=(cell, row, rowIndex) => {
console.log('clicked', cell, row, rowIndex);
}
renderButton() {
const { onLoginEmail } = this.props;
return (
<label htmlFor="LoginButton">
<Button
onClick={()=>this.onDoorListRowClick(1,2,3)}
>
Login button
</Button>
</label>
);
}
react-bootstrap-table
Search
const options = {
clearSearch: true
};
export default class SearchClearTable extends React.Component {
render() {
return (
<BootstrapTable data={ products } search={ true } options={ options }>
<TableHeaderColumn dataField='id' isKey>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
</BootstrapTable>
);
}
}
Action
http://allenfang.github.io/react-bootstrap-table/example.html#manipulation
class ExportCSVTable extends React.Component {
render() {
return (
<BootstrapTable data={ products } exportCSV={ true }>
<TableHeaderColumn dataField='id' isKey hidden export>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
<TableHeaderColumn dataField='action' export={ false }>Action</TableHeaderColumn>
</BootstrapTable>
);
}
}
Export
https://github.com/AllenFang/react-bootstrap-table/blob/3ce59bf44b50aecd49fc27a2b73d4b7b23e5157c/examples/js/custom/csv-button/custom-csv-or-tsv-button.js
class ExportCSVTable extends React.Component {
render() {
return (
<BootstrapTable data={ products } exportCSV={ true }>
<TableHeaderColumn dataField='id' isKey hidden export>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
<TableHeaderColumn dataField='action' export={ false }>Action</TableHeaderColumn>
</BootstrapTable>
);
}
}
Hover, Striped, Condensed Table
striped
class adds zebra-stripes to a table
hover
class adds a hover effect (grey background color) on table rows
condensed
class makes a table more compact by cutting cell padding in half
class HoverStripedTable extends React.Component {
render() {
return (
<BootstrapTable data={ products } striped hover condensed>
<TableHeaderColumn dataField='id' isKey>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
</BootstrapTable>
);
}
}
Large Table
class LargeColumnTable extends React.Component {
render() {
return (
<BootstrapTable data={ products }>
<TableHeaderColumn width='150' dataField='id' isKey>ProductID</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='name'>ProductName</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='price'>ProductPrice</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='name'>ProductName</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='price'>ProductPrice</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='name'>ProductName</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='price'>ProductPrice</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='name'>ProductName</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='price'>ProductPrice</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='name'>ProductName</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='price'>ProductPrice</TableHeaderColumn>
<TableHeaderColumn width='150' dataField='name'>ProductName</TableHeaderColumn>
</BootstrapTable>
);
}
}
Scroll Table
class ScrollTable extends React.Component {
render() {
return (
<BootstrapTable data={ products } height='120' scrollTop={ 'Bottom' }> <!-- Available value is Top, Bottom or any number value -->
<TableHeaderColumn dataField='id' isKey>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
</BootstrapTable>
);
}
}
Sort
class DefaultSortTable extends React.Component {
constructor(props) {
super(props);
this.options = {
defaultSortName: 'name', // default sort column name
defaultSortOrder: 'desc' // default sort order
};
}
render() {
return (
<div>
<BootstrapTable data={ products } options={ this.options } multiColumnSort={ 2 }>
<TableHeaderColumn dataField='id' isKey dataSort>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name' dataSort>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
react-router
https://css-tricks.com/react-router-4/
react-router API
https://reacttraining.com/react-router/web/api
Auth
https://themeteorchef.com/tutorials/getting-started-with-react-router-v4
<BrowserRouter>
should be used when you have a server that will handle dynamic requests (knows how to respond to any possible URI).
<HashRouter>
should be used for static websites (can only respond to requests for files that it knows about).
<Route>
<Route>
component is the main building block of React Router. Anywhere that you want to only render something if it matches the location’s pathname, you should create a <Route>
element.
<Route>
expects a path
prop string that describes the type of pathname that the route matches — for example, <Route path='/roster'/>
should match a pathname that begins with /roster
we strategically place the routes for/users/add
before /users
to ensure the correct matching. Since the path /users/add
would match for /users
and /users/add
, putting the /users/add
first is best.
match.path vs match.url
match.url
would be "/users/5"
. Useful for building nested s
match.path
would be "/users/:userId"
. **Useful for building nested
<NavLink>
works the same as <Link>
but gives you some extra styling abilities depending on if the <NavLink>
matches the browser’s URL.
Image uploader
https://codepen.io/hartzis/pen/VvNGZP
https://github.com/baaraak/react-images-upload
https://gist.github.com/hartzis/0b77920380736f98e4f9
https://github.com/FineUploader/react-fine-uploader
https://css-tricks.com/image-upload-manipulation-react/
http://www.hartzis.me/react-image-upload/
https://medium.com/ecmastack/uploading-files-with-react-js-and-node-js-e7e6b707f4ef
https://juejin.im/entry/57b923225bbb50005b794943
http://jafeney.com/2016/08/11/2016-08-11-upload/
https://github.com/Jafeney/Royal
https://www.jianshu.com/p/e9ce78270860
http://react-component.github.io/upload/
Tools
Redux DevTools
Check installed NPM package version npm list --depth=0
Yarn
npm install -g yarn
Webstorm Set indent to 2 space
File name: .editorconfig
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
Webpack
webpack is a module bundler. This means webpack takes modules with dependencies and emits static assets representing those modules.
Configuration file is: webpack.config.dev.js
import webpack from 'webpack';
import path from 'path';
export default {
debug: true,
devtool: 'cheap-module-eval-source-map',
noInfo: false, //Prod: set to true
entry: [
'eventsource-polyfill', // necessary for hot reloading with IE
'webpack-hot-middleware/client?reload=true', //For hot reload. Note that it reloads the page if hot module reloading fails.
'./src/index'
],
target: 'web',
output: { //Webpack do not generate any code, but we should put it here
path: __dirname + '/dist', // Note: Physical files are only output by the production build task `npm run build`.
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: './src'
},
plugins: [
new webpack.HotModuleReplacementPlugin(), //Hot replace module
new webpack.NoErrorsPlugin()
],
module: { // Tell webpack the type of files we handle
loaders: [
{test: /\.js$/, include: path.join(__dirname, 'src'), loaders: ['babel']},
{test: /(\.css)$/, loaders: ['style', 'css']},
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
{test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000'},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'}
]
}
};
Debug
Webstorm debug setting
For ‘React-boilerplate’
- Install JetBrain Chrome Extension
- Change WebPack devtool config to
source-map
(This line) - Run web server (
npm run start
) - Create Run Configuration (Run > Edit Configurations) : Add new
JavaScript Debug
- URL:
http://localhost:3000
- Map your
root
directory (Remote URLs of local files
) withwebpack://.
- URL:
- Right click JetBrain plugin icon, click “Inspect In WebStorm”
Error Handling
Pay attention to imported action and selectors
If React can not find the action or selectors, it will give you some useless information to confuse you. Like this:
uncaught at githubData
at takeLatestHelper
at getSupportDataSaga
TypeError: Object(...) is not a function
at getSupportDataSaga$ (http://localhost:3000/2.4e77eae8f36a2ed5cbf2.hot-update.js:145:139)
at tryCatch (webpack:///./node_modules/regenerator-runtime/runtime.js?:65:40)
at Generator.invoke [as _invoke] (webpack:///./node_modules/regenerator-runtime/runtime.js?:303:22)
at Generator.prototype.(anonymous function) [as next] (webpack:///./node_modules/regenerator-runtime/runtime.js?:117:21)
at next (webpack:///./node_modules/redux-saga/es/internal/proc.js?:311:27)
at currCb (webpack:///./node_modules/redux-saga/es/internal/proc.js?:387:7)
at runSelectEffect (webpack:///./node_modules/redux-saga/es/internal/proc.js?:690:7)
at runEffect (webpack:///./node_modules/redux-saga/es/internal/proc.js?:433:1124)
at next (webpack:///./node_modules/redux-saga/es/internal/proc.js?:315:9)
at proc (webpack:///./node_modules/redux-saga/es/internal/proc.js?:270:3) # Lib
material-ui https://github.com/mui-org/material-ui
Text input local state example https://openclassrooms.com/courses/build-web-apps-with-reactjs/handle-user-input
https://codepen.io/gaearon/pen/wgedvV?editors=0010
react-widgetshttps://github.com/jquense/react-widgets
Note
React Template
https://thefront.maccarianagency.com/
React Skeleton
Pluralsight-redux-starter React-slingshot
Starter tutorial
http://chenglou.github.io/react/docs/reusable-components.html#mixins
https://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html
https://www.sitepoint.com/how-to-build-a-todo-app-using-react-redux-and-immutable-js/
great redux course: https://egghead.io/courses/getting-started-with-redux
https://www.fullstackreact.com/articles/react-tutorial-cloning-yelp/
test case on angular