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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.