As far as I can tell, if I pass a parent component state down to a child, then that child gets the live state of the parent.
So a change made in the state of the parent is immediately also available in the child via the prop that it came on.
Is this correct?
It's basically the same mechanism as anywhere else in the language, as you'd expect. Primitives are passed by value and variables that aren't primitives will be passed by reference.
React takes care internally of the updating of props, so that children always have the most up-to-date value of the prop.
This is the lifecycle method that is called when receiving new values for props.
However, make sure you respect the infrastructure put in place and the exposed API that React gives you.
Short answer: props are passed by reference.
The reason it can be confusing: if you change the parent's state by hand (bad practice!), the object will change in the child component, too. But won't trigger re-render! (The child component won't "know" that its props has changed.) So you won't see the UI change.
However if you change the parent's state with setState (the preferred practice), the child will be notified, that it must re-render itself.
If you pass down the state of the component as props to its child, then if the state of the parent component changes it re-renders, which will also re-render its children with the refreshed properties. The children don't directly listen for the state change like the parent does, they are simply re-rendered as as result of its parents state change and updated.
Take a look at this - https://facebook.github.io/react/docs/multiple-components.html. It will help you get your head round how this concept works. Hope this helps!
When the state of a component is changed, then the component is re-rendered by React. While doing that , its child components are also re-rendered, which causes changes in them also.
No, they will not be duplicated, you will access to those props by reference, because they come from a single object wich defines them, and then pass them as a reference to the child objects.
You can take a look to the official documentation here: https://reactjs.org/docs/react-component.html.
I suggest to use a stateless mechanism to handle large data, expecially if shared.
Personally I use mobx (https://github.com/mobxjs/mobx) wich is a great framework to create stateless apps.
With this method you can handle data and state updates in a single component, called Store, and use components to render html only, and not to handle data, wich is a great boost on application performances.
Related
Whenever I use Frameworks such as React , Vue or anything else. I see that every value (input value, select value ...) is always being emitted through events to parent. I don't really get why this is good. It takes more ressources / time to pass it to the parent component. Why doesn't the component handle its data by itself?? Why should every single value inside a child component get passed to the state of the parent to make the handling of the data ?
For example, I generally see the loading of the APIs in the parent and then the values of the API get passed down through props or Redux/Vuex. Why can't we get the API values inside the child directly when it's being mounted instead of having to pass it down on many levels or through the local store
It's perfectly valid to have a state inside reusable component, especially if it holds users input. You can still provide it with callbacks in props, which respond to onChange, onBlur or other events based on your needs, or you can communicate with your reusable component via refs, which is fairly flexible way to get user input.
The important thing is, that the reusable component should be as much independent on it's environment as possible. If you don't provide it with a state, the component (in case of your Pickers) will be dependent on props passed down from its parent expressing it's current user input on every rerender and on callbacks updating its current input somewhere higher in component hierarchy on every change, which is not what you want in every case, and it already forces you to make relatively large adjustments in you parent component, which misses the point of reusability.
I have 2 stateful class-based components nested within my main app, a parent class-based component. From child component 1, I've successfully called a parent callback method. From within that parent callback I want to call a method of child component 2, so I can setState of #2 without re-rendering the parent component. I've seen that many devs make the children stateless or even just omit them. However, React encourages devs to "componenatize" ... pointers plz!
if that's the case then you shoud consider lifting the state up to the parent: https://reactjs.org/docs/lifting-state-up.html
your child component should only then call parent methods to update the state, that way, you will have a unidirectional flow of data as what a react app should be. Basically, it encourages you to have a single source of truth and ensure synchronisation of data across your app. Besides it removes unnecessary logic like what you are doing right now:
What does the "single source of truth" mean?
Storing the data in the parent's state and then allowing both children to update it via setStates wouldn't violate the concept of "componentizing" as long as the two children have narrowly declared inputs. If one child needs to update data inside another child, you can jump up a context level and store it in the parent- then an update of the data from either child will trigger a render of both children ensuring the display stays synchronized with the data while keeping the data in a single place (with the parent instead of split between the children).
Bingo, yes I can use a "React ref" to call an instance method of a child component. A ref is an attribute on a component instance. So, right now my child component uses its componentDidUpdate to call a callback in my parent, and the parent callback then uses refs to call an "update" method of specific child components. These update methods setState on child component and voila.
So a colleague explained that calling setState in my main app actually will call setState on all children components (related by JSX expressions). Even though I liked the idea of nesting my event handlers within their relevant child components, it seems that the best practice pattern is to have all handlers in the main app, setState in the main app, then let React do its thing
So I have a component which the state is updated multiple times a second by a child element.
To prevent over-rendering i use the shouldComponentUpdate on the other children to make sure they don't re-render too much.
The element of the state that is updated is required by another child further down the tree.
I would only like that child element to rerender, and not the intermediary children, again, to avoid over-rendering.
How could one do that?
I would only like that child element to rerender, and not the intermediary children, again, to avoid over-rendering. How could one do that?
You can't via the traditional method of passing the state down as props. A change in state in the parent component cannot trigger a re-render on the grand-child component C without triggering a re-render on the child component B first.
For a component to update a child, it needs to go through its life-cycle before it can pass down new props to it.
To my knowledge, the only way around this is to use a state management library, such as Redux or MobX, or use the React Context API and move that state variable there and then "consume" it in your grand-child component.
That being said, unless your tree is multiple levels deep and you don't see any performance issues, I would consider keep using shouldComponentUpdate() like you are already doing.
maybe this is very basic, but I'm still new to react:
I want to have different types of components - with (possibly) no relation to each other - that re-render on changing one specific value in my application. I tried the Provider store of mobx, but of course I received warnings, that you should not change the value of stores.
So for example
<RootElem>
<SimpleComp1>
.....
<ReRenderMeOnRootElemStateChange1 />
.....
</SimpleComp1>
<SimpleComp2>
.....
<ReRenderMeOnRootElemStateChange2 />
.....
</SimpleComp2>
</RootElem>
and the re-rendered components should have acces to the new value/state of the RootElem, so that they can change based on this new value.
What is the best way to do that? Where should I store my observable value for the re-render, and how can I make components listen to it, even if they are no children of the state changing component? I dont' want to pass the props all the way down to every single component, that should re-render on changing the observable value :)
Furthermore I'm wondering if you can make a component listen to another one's changes, even if they have no relationship to the each other in the component tree (except the application's root component).
Thanks!
React components re-render automatically by default when they receive new props. So if you simply pass values from <RootElem> down your component tree via props, everything should work as intended and the sub-components will re-render with the new value.
You can control whether or not a specific component should re-render by using its shouldComponentUpdate hook. I'd say that most of the time you won't need this unless you're trying to make a specific performance optimization.
You can also pass new values to the sub-components using context, though this approach is generally discouraged unless you have some very specific use cases for it and know what you're doing.
Is there a React-okay way to pass new props to children without re-rendering the parent? Nothing in the parent component is changing except that new props are being passed to that component which are being passed through to its children. I thought context might be appropriate in this situation but it seems like the documentation states otherwise.
It depends what you mean by React-okay. You can in fact use contexts for this, but I don't recommend it. It's much easier to reason about and debug props flowing down directly through your view hierarchy, and if the parent isn't changing at all the render function should be quite cheap to execute.
If it isn't cheap, you may want to rethink how you're structuring your components. For example, you may want to split off the expensive part into a separate component that only gets rendered when relevant props have actually changed, or at least secure the expensive functionality behind a conditional props check.