React pass Array from Parent state to child state - javascript

I have a parent component holding a state called nodes which is established as an array. I am trying to pass this.state.nodes to a child component and have that component have the array as part of the child component state, but it's not working. Here is the code:
<ChildComponent nodes={this.state.graphNodes}/>
This is in the return statement. After some testing/console logging I know the prop is being passed.
In the child component, I have:
this.state = {
nodes: this.props.nodes,
links: [],
totalNodes: [],
totalLinks: []
}
But when I try to reference it or map it or do anything with it in the child component render or return it's telling me it's an empty array.

Since graphNodes is in a component state, i think its initial value should be an empty array, and you are initializing state with props.nodes at constructor, since constructor renders only once at initialization stage of the component at that moment graphNodes must be an empty array, after you change the parent component state, the state in the child component will not update. That makes graphNodes state always an empty array.
Why don't you use props directly, if you don't have to change the graphNodes values in the child component you can use it directly from props.
If you really want map props to state, you have to do it in componentDidUpdate lifecycle method with proper conditions

All of the comments were dead on. Using this.props.nodes directly instead of trying to put it in child state was the perfect solution. Thanks to all who replied!

Related

how to prevent children component re render, when state/props parent component changing?

right now im have tree component like this
<UserOrderApproval>
<Table>
<TableRow>
<ComponentList />
</ChildrenProps1>
</Parent>
</UserOrderApproval>
im take props from redux in UserOrderApproval component, and passing that props to every children component. The problem, when children component make some change in redux, the state from UserOrderApproval component will change & make all children component re render & make component life cycle run again. How to do prevent this?
How best practice to passing props from parent to nested children like this?
Many Thanks
As KuchBhi said, you'll need to use the shouldComponentUpdate lifecycle method.
shouldComponentUpdate is called any time when new props or state are passed to the component and by default returns true (might only return true for updated props, not 100% sure). The method accepts two parameters: nextProps and nextState. You can then compare these to this.props and this.state to decide whether you should update or not.
The default/typical implementation of this method is something along the lines of this (pseudo):
shouldComponentUpdate(nextProps, nextState) {
//Really it's a deeper equality check, not just the props/state object
return this.props !== nextProps || this.state !== nextState;
}
What you can do as an alternative is build this out a bit more with cases where false is returned. Here is an example from one of my projects where I only want to rerender when two specific props are different:
shouldComponentUpdate(nextProps) {
const minUpdated = this.props.min !== nextProps.min;
const maxUpdated = this.props.max !== nextProps.max;
return minUpdated || maxUpdated;
}
The component also has the props such as scale, align, width, etc. but I don't want to update when I receive those as new props so I don't check to see if they're not equal.
You could essentially just return false in this method and never update after the initial load, but I would avoid that as it defeats the purpose of react.
edit: As varoons said, this is likely a great scenario for you to use the new context API and I highly recommend looking into it, but it is useful to know about component lifecycle methods as well.
Use shouldComponentUpdate(), pure components, or connect redux to only the child components that need them.
https://reactjs.org/docs/react-component.html#shouldcomponentupdate
https://reactjs.org/docs/react-api.html#reactpurecomponent
This is a good scenario to use React's context api as this seems like a prop drilling case - You are passing data down to components that do not use it.
You could make UserOrderApproval(assuming it is the parent connected to the global state/redux) the context provider and ComponentList the consumer. This way only the components handling/using the data will re-render.
https://reactjs.org/docs/context.html
https://scotch.io/tutorials/get-to-know-reacts-new-context-api

Is the react state meant to be used within the component it is defined?

Should react component state is meant to be used in the component in which it is defined?
I faced a scenario, where a component state is updated by two different components and is passed as a prop to its child. But never used in the component where it is defined.
For example: I have a component CommonComponent which has a state, 'stateObj' and it has two child components ChildComponent and ModifyComponent.
I have one more component, CreateComponent which is a parent of CommonComponent.
I have two cases here:
During create action, CommonComponent receives props from CreateComponent and updates the state- 'stateObj' and is passed as a prop to ChildComponent
During modify action, ModifyComponent updates the state of CommonComponent using a callback and in turn the 'stateObj'
is passed as a prop to ChildComponent
Is this a valid way of using the component's state? As I understood, The state is meant to be used by its component in which it is defined. But, here I am not using the 'stateObj' in CommonComponent. but, i am just using it to send data to its child components. Am I using the state in a right way? or is there any other way of doing this?
your suggestions are really precious!
Thanks in advance.
You could move the state to CreateComponent instead of having it in CommonComponent. So, ModifyComponent and CommonComponent will have callback props which will update the state in CreateComponent.

Vue: Reasons to use props instead of referencing parent data?

In VueJS, I have seen different ways of accessing parent properties from a component. Say I want to use the parent property items in my component.
First way
The component has a props value bound to a parent property:
.js
Vue.component("example", {
template: "<div></div>",
props: ["myItems"]
});
.html
<example v-bind:my-items="items"></example>
Second Way
The child component accesses a parent's properties directly, like this:
this.$parent.items
Question
Is there a reason to use the more elaborate first method over the second? Is there an overhead to "duplicating" data like that, vs. accessing it directly when needed?
The props should be mutated in the parent component, according to the official doc :
All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. This prevents child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to understand.
In addition, every time the parent component is updated, all props in the child component will be refreshed with the latest value. This means you should not attempt to mutate a prop inside a child component. If you do, Vue will warn you in the console
So in order to update props from child component you should use this.$emit event and send the new value in order to handle the update in the parent one.

Can't use state value as props for child component

In my react js app, I can't seem to use the state value as props for the child component.
In the parent component, constructor, the app has a null state called selectedWarehouseID.
This state(selectedWarehouseID) should update with some information in the componentWillMount() method.
Now, in the render method of the parent component I am embedding another child component that has this state as a props.
<ItemChooser
productsByWarehouse = { this.state.selectedWarehouseID }
/>
Now here's the problem, in the child component, the value of this.props.productsByWarehouse is always null. I found a nice explanation of why this happens, but how to wait for the data that updates in the parents componentWillMount() to access the updated value of the state that being passed in the child component props?
Possible solutions are:
1. You are storing the props value in state of child component so, Update the state of child component whenever any change happen to props values (state of parent). For that use componentWillReceiveProps lifecycle method.
componentWillReceiveProps():
is invoked before a mounted component receives new props. If you need
to update the state in response to prop changes (for example, to reset
it), you may compare this.props and nextProps and perform state
transitions using this.setState() in this method.
Like this:
componentWillReceiveProps(newProps){
this.setState({
value: newProps.productsByWarehouse
});
}
Note: Replace value by the actual key in which you are storing the value.
2. Don't store the props values in state of child component, directly use this.props.productsByWarehouse, Whenever you change the parent state values, child will automatically get the updated value in props.

Does React rerenders component when a prop is changed

Suppose I have two components named Parent and Child. In Parent component I have a state named lastName which is passed to Child as a prop. Now after initial rendering of Child and Parent, if the lastName in Parent changed, will it cause Child component to rerender?
Yes, if you set the property via setState. However, re-render in React isn't something you should be afraid of, it's very efficient due to Virtual DOM usage.
In the child component you should use the following
shouldComponentUpdate(nextProps){
return this.props.lastname !== nextProps.lastname
}
https://facebook.github.io/react/docs/component-specs.html#shouldComponentUpdate
After that, in the child component you might need to update the state. To achieve that you can use componentWillReceiveProps(nextProps)
componentWillReceiveProps(nextProps){
this.setState({
lastname: nextProps.lastname
});
}
The Child component is only re-rendered when props lastName is being used in Child's render function and Parent use setState function to change lastName. Remember, React is one-way dataflow, if you want to re-render Child component right inside the Child, you must call an event which also trigger setState back to Parent component

Categories