"passthrough" children don't re-render when parent changes
See original GitHub issueGiven the following Components with the following implementations:
home.js:
render () {
return (
<div className="home">
<Router>
<Route path='/'>
<span>Hi from Index</span>
</Route>
<Route path='/user/martin'>
<span>Hi Martin</span>
</Route>
</Router>
</div>
)
}
router.js:
componentDidMount () {
var self = this;
history.on('pushstate', function(pathname) {
self.setState({});
})
history.on('popstate', function(pathname) {
self.setState({})
})
}
render () {
return React.createElement('div', { className: 'Router' }, this.props.children);
}
route.js:
render () {
if (!match(this.props.path)) return null;
return React.createElement('div', { className: 'Route'}, children);
}
I’m running into the situation that since I’m not creating the <Route>
in the parent and passing it through from the owner, the children do not re-render when the parent’s state changes.
What’s the best way around this? Seems like a pretty common use case.
Issue Analytics
- State:
- Created 8 years ago
- Comments:12 (3 by maintainers)
Top Results From Across the Web
this.props.children not re-rendered on parent state change
As fas as I understand, if setState() is triggered, render function of Container component is called and all child elements should be re- ......
Read more >The mystery of React Element, children, parents and re-renders
Looking into what is React Element, exploring various children vs parents relationship in React, and how they affect re-renders.
Read more >How to use Props in React - Robin Wieruch
Since every state change in a component (here the parent component) causes a re-render of this and all child components, the child component ......
Read more >Avoiding React component re-renders with React.memo
A component can re-render even if its props don't change. More often than not this is due to a parent component re-rendering causing...
Read more >Using forwardRef in React to clean up the DOM
React forwardRef is a method that allows parent components pass down (i.e., “forward”) refs to their children. Using forwardRef in React gives ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This is intentional. It is an optimization we’ve had for a long time and extremely rarely does it ever show up as an issue (as evident by the fact that @syranide didn’t even know about it).
Here is an example of one kind of optimization you can do (manually or automatically): https://github.com/facebook/react/issues/3226
It is also useful for container components that only updates their own state but their parents doesn’t rerender. E.g. a scrolling surface.
We do support mutation of your own state as a convenience but we do make certain assumptions about your code style.
This optimization relies heavily on the hard requirement that
render
must be pure, which is the only hard FP requirement of React:render
should be idempotent. I.e. it should render the same thing regardless when it is called. Neither of these examples uses idempotent render functions since they’re reading from (globally) mutated state. (match
andDate
are not immutable) We’ve been thinking about ways of trying to enforce that. The ideal solution is to put time into your own state, but as a convenience you can callforceUpdate
on something that you know is reading from global state whenever it changes. I.e. the thing callingmatch
orgetTime
needs to callforceUpdate
.render
should not cause side-effects. Even if you use mutable state in your objects, you shouldn’t mutate them within the render.ReactElements and their props are immutable. That is already enforced through
Object.freeze
and warnings. However, it is ok for state within them to be mutable. E.g.<Foo bar={this.state.mutableObject} />
We do have one heuristic. We assume that you won’t combine mutable state with reusable elements. E.g:
This last part is a heuristic assumption which has a theoretical case that doesn’t violate any of the other rules but still breaks. This case has never showed up yet AFAIK, because it is so awkward and unnatural way to structure your app in React.
However, the OP isn’t related to that, this is simply breaking rule number 1.
render
should be idempotent.Awesome, yah I’m looking forward to that.
Appreciate all the help guys – keep up the great work.