How can I call child component setState from parent component - reactjs

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

Related

react parent send "event" to child

I am running some tests with react to find out a way for a parent to send an "event" to a child component. In the test application, the parent (CounterController) has a button. When the button is clicked, the parent shall send a reset "event" to the child (Counter) to reset the current count. Like below.
I am new to react, and can not find a way to dispatch/receive events or messages between components. I had a thought to mark the "reset" request as a "state" in the parent, then pass it to the child through props. Then the child clear the "reset" state, through a callback function, to avoid repeating "reset" requests. However, I got the code run into an infinite loop. Here are my codes.
The parent component - CounterController
The child component - Counter
the error logs
I do not feel that I am using react the right way, by asking the child to do something from the parent. Anyway, any idea about how to implement this app in react? How should the data flow be built correctly? Thanks!
You can move up the counter state on the parent ‘CounterController’
and then you pass the counter and setCounter as props to ‘Counter’
You don’t need ‘reset’ state
I am posting my thoughts about using react (as a beginner), and my solution to the app.
treat the react components as the "view" of the application, and maintain the data and controls in the hooks.
create a custom hook to wrap up all data and controls.
create an instance of the custom hook in the top component - display the data in HTML elements and bound controls to buttons to build the app UI
Here are my codes for this simple UI
UI
useCounter hook
counterController component
counter component
Move "count" state from child component (Counter) to parent
component (CounterController).
Pass count state as prop to child component.
Pass increment and decrement methods from parent to child component through props.
Note: Remove reset state, it's not required anymore.
Sandbox link : https://codesandbox.io/s/infallible-platform-vo4qtv?file=/src/CountController.js

React - Passing Props across the component tree

I am relatively new to React and I was wondering if you could pass components across the component tree without having to create the state variable in the parent component.
Things I understand:
You could pass props down from parent to child.
You cannot pass props up from child to parent.
I also understand that you could use context API's to avoid prop drilling. However, the Context.Provider has to be above the Context.Consumer. So that would mean I would have to create the state variables in the parent class. If I want to share the same state between two child components.
There have been times in my React application where I was forced to create a state variable in the parent to share it across two child components. Is there any way I could use the context API or some other method to create the state variable in one of the child components and share that state with another child component.

Trigger a function in a child component

There is some related threads, and a lot of opinions on this subject so I will try to summarize my findings. Notice I am a beginner so this is my best bet, and the data I gathered from related posts and this.
In general most people agree that if the parent call's a child it is bad practice. In the related post for this article there is an accepted answer, where the person answers that it is a bad practice but possible. #mat sz answer directed me on the right path. I have updated my sample for others to see. I pass a parameter to my child component. In the child component I add a listener for changes on that parameter:
useEffect(() => {
if (props.toggleClose != null) {
setToggleJobTable(false);
}
}, [props.toggleClose]);
I just toggle that parameter between true/false in my parent. Not beautiful but my best bet on how to do this in react.
Original question
I found a lot of samples in here on how to pass variables to child components, how to raise events from child components to parent components, and even how to pass a function to a child component from parent component. But what about last scenario. How to call a function in a child component from the parent. In this sample I would like to trigger the closeAll function in the child component from the parent:
https://codesandbox.io/s/toggle-all-qxkgy?fontsize=14&hidenavigation=1&theme=dark
I still dont have an answer on this, but a lot of good input in the posts. For me it sounds like the right approach here would be parsing a parameter to the child as parameter. My question is then, if I pass a parameter to the child component. How do I toogle when the parent changes that value, then my closeAll function in the child is called?
It is also stated that it could be wrong design. If you look on my very simple sample how should it else be designed? All input are welcome. I have very little experience with REACT so I am trying to understand how an experienced REACT developer would solve this simple task/sample.
It's not possible, parent components are not able to access the functions inside of child components.
You could use something like Redux or MobX to create a global state and then rely on global state for that, or you, ideally, should restructure your code in a way that does not require this, for example if your function (the one that has to be called inside of parent) changes state of a child component - move that state to the parent component, and then provide that state via props to the child component (along with a setter function, if required).

Re-render logic for children of parent which updates muliple times per second

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.

In reactjs, are props pass by value or pass by reference?

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.

Resources