Reputation: 963
So I'm at a bit of a loss here for what to do and would love some recommendations.
I have a quizzing app that has a timer for a question. The parent contains the timer object which uses a callback to set the number of seconds remaining like so:
const [seconds, setSeconds] = React.useState<number>(null);
const timer = React.useRef<Timer>(new Timer({duration: 10, callback: i => setSeconds(i)}));
...
return (
<Context value={seconds}>
...
)
The parent passes the seconds around to the descendants through a context because a child and grandchild both need access to the number of seconds remaining to show a timer.
The problem is that the update interval is every .1 seconds, and as a result the children and all subsequent descendants rerender which is a huge issue.
Is there a way that I can only have only the things that rely on the timer rerender?
I have all of my components wrapped in React.useMemo and am accessing the seconds with React.useContext.
Upvotes: 1
Views: 953
Reputation: 12174
The problem is that the update interval is every .1 seconds, and as a result the children and all subsequent descendants rerender which is a huge issue.
This isn't entirely true. Only the specific context consumers will re-render based on value
changes.
Is there a way that I can only have only the things that rely on the timer rerender?
Aside from using Context, Yes there is another way.
Extract a TimerComponent
from your context.
Use redux
to dispatch onTimerChange
action from your TimerComponent
// in mapDispatchToProps
updateTimer = (duration) => {
dispatch({ action: 'TIMER_UPDATED', payload: { duration }});
}
// In reducer
case 'TIMER_UPDATED':
const duration = action.payload.duration;
return { ...state, duration };
duration
prop in store.mapStateToProps(state) {
return {
duration: state.duration;
}
}
duration
will cause the "consumer" component to re-render.componentDidUpdate(prevProps) {
if (prevProps.duration !== this.props.duration) {
// do something
}
}
or pass duration
to child
render() {
const { duration } = this.props;
return <SomeItem duration={duration} />;
}
Upvotes: 1