在一个特定的业务案例中,我有一系列线性排列的组件,但是顺序可能会改变。例如,我们有一个父组件:
export const Component = () => {
const [data, setData] = useState(null);
const [nextComponent, setNextComponent] = useState(null);
return (
//... component code here
{nextComponent}
);
}
在Component
代码中将包含可以更改下一个组件的按钮:
onClick={() => setNextComponent(<SomeComponent data={data} setData={setData} />)}
如果通过在data
中调用setData
来更改SomeComponent
,则该组件不会使用新的data
道具值重新呈现。
我知道这与SomeComponent
处于状态存储有关,但无法理解为什么data
不会在SomeComponent
中更新-当然data
只是指向内存位置的指针,因此在父级和子级之间应该具有相同的值吗?
答案 0 :(得分:1)
这是因为仅当函数data
作为SomeComponent
回调的一部分被调用时,setNextComponent
道具才针对onClick
进行更新。
做到这一点的“正确方法”是将对SomeComponent
至关重要的数据保持在其父状态下,然后将其作为该孩子的有条件渲染的一部分传递给下一个。
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} />);
}
此外,您应该考虑不将组件存储在状态中。这是不好的做法,通常无法按您期望的方式工作。