我有以下代码:
export default function Parent() {
const children1 = someArrayWithSeveralElements.map(foo => <SomeView />);
const children2 = someArrayWithSeveralElements.map(foo => <SomeCheckbox />);
return (<>
{children1}
{/*Some other components*/}
{children2}
</>)
};
对于给定的元素foo
,存在一个SomeView
组件,该组件根据SomeCheckbox
的状态有条件地呈现。我在想办法让复选框的状态影响兄弟视图组件的呈现时遇到了麻烦。
通常情况下,解决方案是在父组件中声明状态钩子,并将其传递给每个子组件,但由于兄弟组件是通过foreach循环呈现的,因此不可能这样做。
我目前的解决方案是在循环中也为每个foo
生成状态钩子,但这感觉有点hacky,因为最好避免在循环中创建钩子(someArrayWithSeveralElements
在安装后不打算更改是没有价值的)。
是否有更优雅的替代方案来解决这个问题?
解决方案是您所需要的,您需要在父组件中创建一个状态并将其传递给子组件。这对单个组件或一组组件都有效,区别很简单:使用array或object作为状态。
const [checkboxesStatus, setCheckboxesStatus] = useState({// fill initial data});
const children1 = someArrayWithSeveralElements.map(foo =>
<SomeView
visibile={checkBoxesStatus[foo.id]}
/>);
const children2 = someArrayWithSeveralElements.map(foo =>
<SomeCheckbox
checked={checkBoxesStatus[foo.id]}
onChange={// set new value to foo.id key}
/>)
export default function Parent() {
const [states, setStates] = React.useState([]);
const children1 = someArrayWithSeveralElements.map((foo, i) => <SomeView state={states[i]} />);
const children2 = someArrayWithSeveralElements.map((foo, i) => {
const onStateChange = (state) => {
setStates(oldStates => {
const newStates = [...(oldStates || [])]
newStates[i] = state;
return newStates;
})
}
return <SomeCheckbox state={states[i]} onStateChange={onStateChange} />;
});
return (<>
{children1}
{/*Some other components*/}
{children2}
</>)
};
使用父组件中的状态。注:state的元素可以是undefined
。