Reputation: 27
In a particular business case, I have a series of components that are laid out in a linear fashion, however the order of which may change. For example, we have a parent component:
export const Component = () => {
const [data, setData] = useState(null);
const [nextComponent, setNextComponent] = useState(null);
return (
//... component code here
{nextComponent}
);
}
Inside the Component
code would be buttons that can change which component is to come next:
onClick={() => setNextComponent(<SomeComponent data={data} setData={setData} />)}
If data
changes by calling setData
within SomeComponent
, the component is not re-rendering with the new data
prop value.
I understand this is something to do with the SomeComponent
being stored in state, but can not understand why data
does not update in SomeComponent
- surely data
is just a pointer to a memory location, and should therefore have the same value across the parent and child?
Upvotes: 0
Views: 57
Reputation: 22899
This is because the data
prop is only updated for SomeComponent
when the function setNextComponent
is called as part of your onClick
callback.
The "right way" to do this is to hold the data that matters to SomeComponent
in its parent's state, then pass it down as part of a conditional render of that child.
const ChildComponent = ({ data, setData }) => (
<React.Fragment>
<span>Current Data: {JSON.stringify(data)}</span>
<input onChange={({target}) => setData(target.value)} placeholder="Enter New Data" />
</React.Fragment>
);
const ParentComponent = () => {
const CHILD_TYPES = { signIn: SomeComponent, signOut: OtherComponent };
// keep track which component you want to be showing based on parent state
const [activeComponentType, setActiveComponentType] = useState('signIn');
// keep track of the data required for the child component(s)
const [data, setData] = useState(null);
// find and use the correct class for the current child type
// (you could do this without an extra variable by using `React.createClass`)
const ActiveComponentClass = CHILD_TYPES[activeComponentType];
return (<ActiveComponentClass data={data} setData={setData} />);
}
Also, you should consider not storing components in state. It's bad practice and usually won't work the way you expect.
Upvotes: 1