从父数组访问子数组的状态



父元素访问子元素数组状态的方法是什么?

通常你会"取消状态"。从子元素到父元素,但由于不能在循环中使用钩子,那么如何对子元素数组执行此操作呢?

例如,一个子数组,每个子数组中都有一个复选框,并且来自父数组,试图找出复选框是否被选中。

通常你会"取消状态";从子元素到父元素,但由于不能在循环中使用钩子,那么如何对子元素数组执行此操作呢?

在循环中使用钩子是可以的if循环迭代的次数永远不会改变,被循环的项的顺序永远不会改变。(例如,如果您有一个使用静态数组定义其表单字段的组件,则可以在该数组的循环体中使用钩子。)

也就是说,您可能最好使用单个useState调用和Map的复选框到标志项。将其保存在父类中,让父类根据需要访问它,并在呈现复选框时将复选框的标志传递给该复选框。

const { useState } = React;
const getDefaultCheckboxState = () => new Map([
["a", false],
["b", true],
["c", false],
]);
const Example = () => {
const [flags, setFlags] = useState(getDefaultCheckboxState);
const onCheckboxChange = ({currentTarget: {name, checked}}) => {
setFlags(f => {
f = new Map(flags);
f.set(name, checked);
return f;
});
};
console.log(`Checkboxes: ${[...flags].map(([name, flag]) => `${name}: ${flag}`).join(", ")}`);
// (This rendering is repetitive and could be done in a loop, but I'm
// assuming in the real situation they're rendered in various different
// places.)
return <div>
<div>
<label>
A:
<input type="checkbox" name="a" checked={flags.get("A")} onChange={onCheckboxChange} />
</label>
</div>
<div>
<label>
B:
<input type="checkbox" name="b" checked={flags.get("b")} onChange={onCheckboxChange} />
</label>
</div>
<div>
<label>
C:
<input type="checkbox" name="c" checked={flags.get("c")} onChange={onCheckboxChange} />
</label>
</div>
</div>;
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

在这个例子中我对return的评论,这里是一个在循环中渲染这些的例子:

const { useState } = React;
const getDefaultCheckboxState = () => new Map([
["a", false],
["b", true],
["c", false],
]);
const Example = () => {
const [flags, setFlags] = useState(getDefaultCheckboxState);
const onCheckboxChange = ({currentTarget: {name, checked}}) => {
setFlags(f => {
f = new Map(flags);
f.set(name, checked);
return f;
});
};
console.log(`Checkboxes: ${[...flags].map(([name, flag]) => `${name}: ${flag}`).join(", ")}`);
return <div>
{[...flags].map(([name, checked]) => <div key={name}>
<label>
{name.toUpperCase()}:
<input type="checkbox" name={name} checked={checked} onChange={onCheckboxChange} />
</label>
</div>)}
</div>;
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>


但是re钩子在循环中,只是为了完整,这里有一个在循环中使用useState的例子:

const { useState } = React;
const checkboxDefinitions = [
{name: "a", default: false},
{name: "b", default: true},
{name: "c", default: false},
];
const Example = () => {
const checkboxes = checkboxDefinitions.map((def) => {
const { name } = def;
const [ checked, setChecked ] = useState(def.default);
return { name, checked, setChecked };
});
console.log(`Checkboxes: ${[...checkboxes].map(({name, checked}) => `${name}: ${checked}`).join(", ")}`);
return <div>
{checkboxes.map(({name, checked, setChecked}) => <div key={name}>
<label>
{name.toUpperCase()}:
<input type="checkbox" name={name} checked={checked} onChange={({currentTarget: {checked}}) => setChecked(checked)} />
</label>
</div>)}
</div>;
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

我并不是说这是个好主意(例如,我很确定我不会在这里这样做,但我有理由在其他更复杂的情况下这样做)。

最新更新