Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing react-redux from re-rendering whole page when state changes

I am reading several articles about how to prevent react-redux from re-rendering the whole page, when only one little thing changes. One article suggests that instead of wrapping all into one big container (as in figure 1 here) wrapping all into smaller containers (as in figure 2 here). If something changes in Container 2, only Component 2 and Component 3 are getting re-rendered. Component 1 would not re-render.

Figure1 Figure1

Figure2 Figure2

I have following questions:

  • If I wrap everything in smaller containers, I would need "several" global states, for each container one (as indicated with the pseudo-code on the bottom of the figure). Is that common practice?
  • If it is ok to have "several" global states and I would need in some property from Container1 in Container2, I would need to connect that with two global states. To me that feels like it could get messy very quick. Where does what come from?
  • When and where would I use the react method shouldComponentUpdate()? Using the Big Container approach how would I differ which Component should be rerendered?! If implemented in the Components, they would not be "dump" anymore, because they need to access the global state in order to decide whether to re-render or not. I would not be able to reuse Components because every Component has its own special case when to rerender and when not. I am not sure where and when to use shouldComponentUpdate()

Please note that I am pretty new to this and might have made wrong assumptions etc. I basically want to know how not to re-render the whole page, when only one thing needs to be updated. The results from asking google differ a lot.

like image 744
Stophface Avatar asked Oct 17 '22 08:10

Stophface


1 Answers

Your second approach is the way to go, though your definition of a global state is a bit misleading. Basically, you want to have exactly one "global state". This is what is referred to as "store". All components that need to receive parts of the store are connected to it using react-redux' connect function.

Now, connect(...) is actually a HOC which wraps your component and passes only defined parts of the store to it. This way, the component (and its' children) only re-render when its' defined props change.

Don't be afraid to use connect() more often. You just have to be careful what parts of the store you pass to the container and this is exactly where performance can become an issue.

This should answer your first question. The second one is a question of design. Design in terms of how your app and maybe also in terms of how your datasource is structured. As said before, you want to have a minimum of props passed to a component so it doesn't re-render when other parts of the store change.

For the third question, you first have to understand that 'dumb components' can, of course, receive props from their parent components/containers. Dumb just means that they don't get to decide whether a re-render should happen or not. Dumb components are there to present/display data and that's it.

Let's say you have a really simple store:

const store = {
  posts: {
    all: [],
    isFetching: false,
    err: {},
  }
}

And you connect your container to it like this:

function mapStateToProps(store) {
  return {
    posts: store.posts.all,
    isFetching: store.posts.isFetching,
    err: store.posts.err,
  };
}
@connect(mapStateToProps)

And this container has three dumb components it can use:

  1. A posts component, which receives all posts and displays them using another dumb child (pseudoCode, you get the point):

     function posts = (posts) => { 
       posts.map((post, id) => (
         <otherDumbComponent post={post} key={id} />
       ));
     }
    
  2. One to display just a spinner while isFetching

  3. One to display the error if there's one.

Now, if only isFetching has changed, only the second component will re-render and that's it. Oh, and shouldComponentUpdate() is something you probably don't want to use, because, well.. there are many good blog posts about it.

like image 140
VF_ Avatar answered Oct 21 '22 08:10

VF_