React + Redux + PureComponent
https://stackoverflow.com/a/50463828/4312466
by Jordan Enev
HTML
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.7/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/2.0.2/velocity.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/index.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Babel + JSX
const itemsReducer = (state = [], action ) => {
if (action.type === 'ADD_ITEM') return [ ...state, action.payload]
return state
}
const addItem = item =>({
type: 'ADD_ITEM',
payload: item
})
class Item extends React.PureComponent {
render() {
// As you can see here, the `Item` is always rendered only 1 time,
// because we use `React.PureComponent`.
// You can check that the `Item` `Rendered at:` time is always the same.
// If we do it with `React.Component`,
// then the `Item` will be rerendered on each List update.
return <div>{ this.props.name }, Rendered at: { Date.now() }</div>
}
}
class List extends React.Component {
constructor(props) {
super(props)
this.state = { intervalId: null }
this.addItem = this.addItem.bind(this)
}
componentDidMount() {
// Add new item on each 1 second,
// and keep its `id`, in order to clear the interval later
const intervalId = setInterval(this.addItem, 1000)
this.setState({ intervalId })
}
componentWillUnmount() {
// Use intervalId from the state to clear the interval
clearInterval(this.state.intervalId)
}
addItem() {
const id = Date.now()
this.props.addItem({ id, name: `Item - ${id}`})
}
renderItems() {
return this.props.items.map(item => <Item key={item.id} {...item} />)
}
render() {
return <div>{this.renderItems()}</div>
}
}
const mapDispatchToProps = { addItem }
const mapStateToProps = state => ({ items: state })
const ListContainer = ReactRedux.connect(mapStateToProps, mapDispatchToProps)(List);
const Store = Redux.createStore(itemsReducer)
const Provider = ReactRedux.Provider
ReactDOM.render(
<Provider store={Store}>
<ListContainer />
</Provider>,
document.getElementById('container')
);