As a dev I want to be able to change the state of component without triggering re-render of children so that I can better optimize the app.
Use cases:
Imagine controlling the visual state of component that is defined by state object as {isVisible: true}, that inside render function, ONLY effects the display property and nothing else.
A form input element that has invisible label that shows up if username is invalid or password is too short and is controlled by {hasErrors: false}, which if true, just appends that element.
Now calling setState({isVisible: false}) or setState({hasErrors true}) will trigger re-render of all* components below the chain when the update was in no way effecting the model and was just a visual update.
*Unless they have shouldComponentUpdate implemented, which again doesn't make sense as that's extra logic for something that could've been avoided in the first place.
So it'd be very useful to have a function like setLocalState() that does not propagates to children components.
Feedback welcome.
Thanks.
I think in React does not differentiate between default component(<div>) and User-defined components so we can not differentiate between parent(<div>) and children component so it would be difficult to distinguish between global/local renders.
@zeel I think I'm not clear. What I'm proposing is:
Assuming we have components A, B, C
and A's render function looks like this:
render() {
return (
<div>
<p className={classNames('err-lable', (this.state.isVisible)? 'active' : null)}>
Something that's either display: none or display: block
</p>
<B someProps={someVals} />
<C someProps={someVals} />
</div>
)
}
And also assume React has successfully completed first render and everything is in DOM
Now later on after some user interaction isVisible needs to be changed. Right now we'd call setState({isVisible: true}) but the problem with that is it'll also call render functions of B and C and they in turn will call their children's render functions until someone returns false from shouldComponentUpdate.
I know React says JavaScript is fast and computing diff is not performance hit but think about it, why? why compute something that hasn't changed, the actual data model.
This is where my proposal comes in, instead of setState we could have setLocalState that by very definitions means, notify React that something in just this component changed.
Here's the flow
ReactDOM.render(....A's setLocalState is calledA's render is called A's vDOM React won't call B's or Cs render functions instead it'll use their already available vDOM's if it knows that they exist, otherwise it'll call them.A's old vDOM with this new one and apply the changes.What's wrong with using shouldComponentUpdate? The state of the child components should be unchanged and can be easily checked.
Component B and C's shouldComponentUpdate should already return false anyway.
But it's fast, very fast - and the state is clear. With hacks like you wish, the state would be out of sync with the virtual DOM. Make totally no sense. You can use then jQuery then for every "visible" toggled element.
When you want to manipulate the DOM directly just use refs and findDOMNode. There are good use cases to use them.
Use an instance variable (like this.xyz) to store your data that doesn't affect rendering.
@yaycmyk They do affect rendering, but not of children, just self.
You can extend components B and C from PureComponent instead of just Component. This way, children render method will only be called if their props (or their inner state) change.
This is basically a Component with shouldComponentUpdate implemented. But this way you don't have to explicitly define it.
Thanks for the issue @NeekSandhu! We do appreciate the time you took to write out your ideas. I'm going to echo what others have said and say that shouldComponentUpdate and by extension PureComponent provide exactly what you want, which is to update a component's render output without updating specific children of that component.
That said, I'm going to close this out as there's an existing solution and we're generally pretty selective when it comes to implementing new public APIs, but feel free to continue the discussion here. Thanks!
How to prevent unnecessary re-render of one of child components? If we are define "key" property it must be used to detect changes. So static value in this property key="1" must be meaning "never update!", but it working not as expected. I mean not working.
So static value in this property key="1" must be meaning "never update!", but it working not as expected
Nowhere does it say that in the documentation. Please check out the docs to see what keys do.
Most helpful comment
What's wrong with using
shouldComponentUpdate? The state of the child components should be unchanged and can be easily checked.