Rerender Descendants Through shouldComponentUpdate

Kent C. Dodds
InstructorKent C. Dodds

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 3 years ago

One problem with using context is that any component in the hierarchy could return true from shouldComponentUpdate without knowing that state in context has changed. In this lesson, we’ll look at how the react-broadcast library can be used to avoid that problem.

[00:00] The purpose of a provider is to communicate state anywhere inside the tree, so that the components can react to state changes. However, something can prevent an entire section of the tree from updating, and that is should component update, which is a performance optimization people can use to prevent React from re-rendering that component and all of its children.

[00:19] This is great, except it totally breaks our use case with the toggle provider. If I put this update blocker around the post here, and then I toggle this, we're going to see the top is updating but the bottom section is not being made aware of those changes.

[00:33] That's because this update blocker, this component that's returning false from should component update, and it's preventing the post from getting the new state and re-rendering with that new state. We need to take things a step further, so that components that are under a should component update false can still be notified of changes to our context.

[00:50] We're going to use a library called React Broadcast to do this. Let's go ahead and come up here to our script tags. We'll add another script tag for React Broadcast. Then we'll go to our toggle provider and re-implement it using React Broadcast.

[01:05] React Broadcast actually does all the context stuff for us. It uses context to establish channels which can be subscribed to by children components when they're rendered. Because it's doing all this stuff for us, we can actually get rid of this render entirely. Instead of rendering the toggle provider.render, we're going to render React Broadcast.broadcast.

[01:28] Inside of here we'll render the children. Then we'll provide two props, the channel which we'll assign to toggle provider.channel, and the value which we'll assign to toggle. Let's change context name to channel. We'll just change toggle to toggle channel.

[01:47] Any time the toggle value changes, React Broadcast will be notified. It will notify also subscribers. Now we'll go to the connected toggle, and we'll subscribe to this channel. We'll get rid of the context types. Instead of returning props.render, we'll return React Broadcast.subscriber. The channel is toggle provider.channel.

[02:13] The subscriber actually takes a render prop, but it takes it as children. It's going to accept the value which is toggle. We'll invoke props.render with toggle. That way, we keep the existing API of the render prop.

[02:26] We'll save this. If we click on this, everything is getting updated, even though the post is wrapped inside of this update blocker which is returning false from Should component update.

[02:37] To review the way this is working, our toggle provider has a channel. It renders the toggle component which is keeping track of the state of the toggle. We render the Broadcast component from React Broadcast with a channel and the value.

[02:54] Then we render all the children which will contain subscribers to this channel. The way that you subscribe is by using the connected toggle, which will subscribe to the channel using React Broadcast Subscriber.

[03:06] Whenever this value changes, our function is going to be called, and will call the render function from components using connected toggle. Now we don't need to worry about anyone returning false from shouldcomponent update.

Michele Gerarduzzi
Michele Gerarduzzi
~ 4 years ago

Shouldn't the intro sentence read "...is that any component in the hierarchy could return FALSE from shouldComponentUpdate..."? Please correct me if I'm wrong. Thanks.

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

Yes! You're correct! Sorry about that 😅

At least the code is correct! 😃

James Talmage
James Talmage
~ 4 years ago

This looks like a good alternative: https://github.com/thejameskyle/create-react-context

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

Yeah! That repo was just created 7 days ago (after this course was released). It's also a polyfill of a proposal for a new context API in React which I believe is based on react-broadcast. Due to this fact, in the future what people learn from this video will still be relevant :)

Dave
Dave
~ 4 years ago

Would you recommend using React Broadcast rather than Providers when sharing state with other components?

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

Hi Dave, This is actually still the Provider pattern using React Broadcast to implement it. So they're not at odds with each other. React Broadcast is just a way to implement the Provider pattern :)

kvrmd
kvrmd
~ 4 years ago

Are you planning to make an updated guide for React 16.3 Context API?