State In ReactJS - reactjs

If there are multiple components at different hierarchy levels that use the same data, should I model the data with different variables represented in the respective states of each component or should I have it as a single field included in the state of a component higher up in the hierarchy, possibly the root element? How does it affect the performance?

What I usually do, to minimize the juggling of states IF every component or thereabouts, needs something from the parent.. I will put that behavior in the parent. So, lets say I have a "Parent component" that makes an api call to get some data. If most of my children needs different splices of data off of that api call response.. I would do..
PARENT
state = from api response
----> Child Component 1 {...slice of state it needs}
----> Child Component 2 {...slice of state it needs}
---------> Sub Child Component 1 {... slice of state it needs from component 2}
Or if I can't really know for sure what data each child needs over time, I'll pass down the whole state from the parent into each of my components. If those child components have sub-components, then the child components will continue to pass the state down thru the props. You can also look into "Context" that is a nice solution if you want to leapfrop all of the passing down, and just have it available to all the children.
I usually don't worry about "performance" unless I'm dealing with literally hundreds of data sets. In which case, I tend to pass down only what the child and its sub-children needs.

Related

Can a component have its own state?

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.

Best way to store data for array of components in ReactJS?

I have an application which on page load, fetches data(an array of objects) from database and displayed it as rows in UI. Each row is a child component which can be created, edited, deleted or reordered. The parent component has a Save button which gets the data from all child components and updates it in database.
There seems to be 2 ways to store this data:
Store all data in the parent component:
The parent component fetches the data, stores it in a state variable and passes it on to the child components. When data in child component changes, it is directly updated in the parent component. When we need to save, the whole state variable in parent can be written to database as it is.
Pros:
All data is maintained in parent as it should be in the database. So fetch and save are straightforward.
Child components are dumb and only display data in UI. Good separation of smart data-components and dumb presentational-components.
Cons:
Whenever a child updates data, parent's state var updates and so all child components re-render since they share the same state data var(am I wrong here? Does react handle arrays state var's element passed as props smartly?). This could be a problem if the list grows long and there are a lot of child components.
The parent component ends up doing almost everything, making it quite complex.
Store each row data in child component:
The parent component fetches the data, and passes it on to the child component. The child component maintains its own data and when data in child component changes, only updates it in its local state var. When we need to save, the parent component will have to ask each child component to provide its data, collate it into an array and update it in the database.
Pros:
On changing a row data, only that child component is re-rendered.
Child components handle their own data, making parent component simpler.
Cons:
Distributed data across child components means collating them for database writes are a pain.
On clicking save button, calling a function in child from parent using refs, which returns child data is not a recommended react pattern.
In React is recommended that the parent component handles the data and distributes that data to children. To avoid re-rendering every child component I would take a look at memo(): https://reactjs.org/docs/react-api.html#reactmemo. This will cache your child component, and decides if it needs to be re-render or not.
To implement this with an Array I would check out this: How do I apply React.memo to all components in an array?

React - How to connect / disconnect children components to data from parent based on click?

Parent component provides data to child component (that displays it) (have multiple children). The child component has 2 buttons connect and disconnect. When connected to should receive and show the data, when disconnected clicked, it should disconnect from data.
How I would do it: child calls method in parent for connect/disconnect,then i would have a flag in parent state and based on that either render child with or without data, then inside child i render props or null if no props provided.
That would mean if I have 10 child components, I would need 10 flags which doesnt seem good, so I 2nd idea:
having the flag insight the child and method for triggering connect/disconnect, render based on if props were provided
My question is, is there a good practice react way of connecting children to parents data flow/stopping data flow without always passing data to children and just rendering/not rendering it based on if child 'wans' to be conencted or not?
Thanks!
Did you try using Redux or Context API?
The two are very similar and it should get what you want.
They basically use 1 store(think of them multiple states are connected to 1 store) and you get data from child components.
After getting your data you can check if user is logged in or not and put your buttons according to this data.
If I was not clear enough feel free to ask any question.
Also official docs for Redux and Context API are:
https://redux.js.org/introduction/getting-started
https://tr.reactjs.org/docs/context.html

How can I call child component setState from parent component

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

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