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>
<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')
);