Passing an object from Redux from React causes unnecessary renders?

react component not 're rendering on redux state change
react prevent child component from rendering
react redux
react component rendering multiple times
mapstatetoprops
redux prevent 're render
shouldcomponentupdate
reselect

Im debugging a performance issue in my app. My top level component App is re-rendering every time the Redux state changes, even if it's props (from Redux) have the same values.

It's passed 2 props from Redux, one is a string and one is an object.

export default connect(state => ({
  name: state.name, // This is a string
  address: state.address // This is an object
}))(App);

It's address (the object) that is causing the issue. Am I right in thinking that this is because Redux's connect function does a shallow compare and thinks that address has changed as it's a new object, even thought the values havn't changed?

Assuming this is correct, I believe the solution is to either memoize address eg using the reselect module, or use shouldComponentUpdate (which seems messier to me). Am I correct that these are the 2 normal solutions?

I agree with your assessment, connect indeed does a shallow comparison, and if the address object is new it will re-render.

I would advise against using shouldComponentUpdate to solve this as it can easily lead to bugs where your App does not update when needed.

reselect is a fine option for the general case, but in your case there can be another option - you could extract from the address object the values in mapStateToProps:

export default connect(state => ({
  name: state.name, // This is a string
  city: state.address.city, // This is a string now
  street: state.address.street, 
  // etc. 
}))(App);

If you need all the values you could just spread the address object:

export default connect(state => ({
  name: state.name, // This is a string
  ...state.address,
}))(App);

5 Ways to Stop Wasting Renders in React/Redux, While learning React/Redux, I noticed some of my components were rendering When we pass a function in props to a component, you can pass a handle Instead of doing Object.values() in the mapStateToProps method to transform a changes, avoiding useless render caused by strict comparisons. Redux keeps a record of what changes happen to your state and in which order, even letting you "time travel" through these changes, it can also be more efficient, context can often cause many unnecessary re-renders, although I haven't read too much into this so take it with a pinch of salt.

use shouldComponentUpdate (which seems messier to me)

Actually, React Redux already does an internal shouldComponentUpdate and only does shallow equality check.

So it's worthless duplicating it in your component.

either memoize address eg using the reselect

This should be your solution as it ensures that connect will skip re-rendering if values are the same.

Immutable Data, Does shallow equality checking with a mutable object cause problems with a persistent object to mapStateToProps prevent React-Redux from re-rendering How can immutability in your reducers cause components to render unnecessarily? emphasizing: If the reducers all return the same state object passed to them,� This means function declarations in mapDispatchToProps only get called once, so they pass the shallow compare test and don’t cause a re-render. So the advantage to not declaring ownProps in mapDispatchToProps is to avoid unnecessary calls to mapDispatchToProps, not to avoid unnecessary re-renders of the connected component.

As far as I understand actually this always returns a new object

export default connect(state => ({
 name: state.name, // This is a string
 address: state.address // This is an object
}))(App);

Say your redux state is updated some value but not name or address, redux will call all mapDispatchToProps in your App and it would return a new object

I would recommend using reselect for this case, it would really help with performance issue.

Hope it helps

Performance, Will caching remote data cause memory problems? particular is heavily optimized to cut down on unnecessary re-renders, and React-Redux For maximum rendering performance in a React application, state should be stored in a and connected list components should pass item IDs to their connected child list items� Passing a new object to a context Provider is essentially a new reference, as the context holds a single value (in this case an object). Context optimization By default, any update to a parent component that renders a context Provider will cause all of the child components to re-render regardless of changes in the context, due to React's

Redux: Re-rendering Caused by mapDispatchToProps, I've worked on a couple of React/Redux projects now, and it was only some of the re-rendering issues I've run into were being caused by incorrectly Learning to pass an object instead of a function in these situations has is to avoid unnecessary calls to mapDispatchToProps, not to avoid unnecessary� Avoid unnecessary renders: React.memo() React.memo() handles memoization of functional components, meaning that if the component will receive the same props twice, it will use previously cached props and run the render() function only once. It is the same method as React.PureComponent for class components. Take this super simple (and a little

Redux isn't slow, you're just doing it wrong - An , In 99% of cases, the cause for bad performance (this goes for any other In this article, you'll learn how to avoid unnecessary rendering when using Redux an object, which is passed onto the wrapped component as props. Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).

How to identify and resolve wasted renders in React, With its introduction of Virtual DOM, React makes UI updates as efficient as they can ever be. in the above picture, and that data has been passed from R to B and then 2 we should consider a few things to stop those redundant renders. new props, the render function is called to create its element tree. Technically, a container component is just a React component that uses store.subscribe() to read a part of the Redux state tree and supply props to a presentational component it renders. You could write a container component by hand, but we suggest instead generating container components with the React Redux library's connect() function, which

Comments
  • You should change your reducer so that it doesn't make a new address object if its value doesn't change.
  • @RemcoGerlich It is not related with the reducer.
  • Everything that changes in the state is related to the reducer, that's the only place where state changes.
  • It's fine if mapState itself returns a new object. What matters is if one of the fields in the return object is a new reference.