I am building a PhotoViewer that changes photos when the user presses left or right. I am using React, Redux, react-router, and react-router-redux. When the user presses left or right, I do two things, I update the url using this.context.replace()
and I dispatch an action to update the currently viewed photo, this.props.dispatch(setPhoto(photoId))
. I am subscribing to state changes for debugging.
Each of the above lines triggers a new state change. Dispatching an action updates the store since I update the currentlyViewedPhoto
and updating the url updates the store because react-router-redux updates the url in the store. When I dispatch the action, in the first rerendering cycle, the component's render
function gets called twice. In the second rerendering cycle, the component's render
function gets called once. Is this normal? Here is the relevant code:
class PhotoViewer extends Component {
pressLeftOrRightKey(e) {
... code to detect that left or right arrow was pressed ...
// Dispatching the action triggers a state update
// render is called once after the following line
this.props.dispatch(setPhoto(photoId)) // assume photoId is correct
// Changing the url triggers a state update
// render is called twice
this.context.router.replace(url) // assume url is correct
return
}
render() {
return (
<div>Test</div>
)
}
}
function select(state) {
return state
}
export default connect(select)(PhotoViewer)
Is this normal that render is called three times? It seems like overkill because React will have to do the DOM diffing three times. I guess it won't really matter because nothing has changed. I am new to this toolset, so feel free to ask any more questions about this problem.
If you are setting state at three different stages then the component will re-render three times as well.
(source)
You can implement logic in shouldComponentUpdate() to prevent unneeded re-renders if you are experiencing performance issues.
I would assume that this is normal. If you aren't having noticeable performance issues, I wouldn't sweat it. If performance begins to be a problem, you can look into overriding the
shouldComponentUpdate
lifecycle method if you are certain that certain state changes won't change the rendered component.Edit: You could also look into extending
React.PureComponent
instead ofReact.Component
if you only need shallow comparison in yourshouldComponentUpdate
lifecycle method. More info here.