Parent 组件在 children 组件列表上调用 child 组件函数
Parent component to call child component function on a list of children component
这就是我现在拥有的。
除重置按钮外的每一行都是一个名为 Item
的 child 组件。一个项目有一个指示其计数的徽章,2 个用于递增、递减的按钮和一个 delete
按钮。名为 ItemList
的 parent 组件包含重置按钮和 children。由于 parent 维护 children 列表,因此删除功能也在 parent 中实现。除了 reset
按钮外,我需要的所有功能都已完成。
重置按钮可以被认为是一个主按钮,点击后应该能够重置所有 children 的 count
。计数由每个 child 保持为状态,因此理想情况下 parent 应该调用它包含在列表中的每个 child 的重置函数,但我无法为此提供代码特定部分。我不确定如何访问每个 child 的重置功能并将其应用于列表中的所有 children。
项目代码 (child)
function Item({ deleteHandler }) {
const [count, setCount] = useState(0);
const [cName, setCName] = useState("badge bg-warning text-dark");
useEffect(() => {
setCName(count !== 0 ? "badge bg-primary" : "badge bg-warning text-dark");
}, [count]);
const increment = () => {
setCount((prevCount) => prevCount + 1);
};
const decrement = () => {
setCount((prevCount) => prevCount - 1);
};
//this is what needs to be called
const reset = () => {
setCount(0);
};
const zero = "zero";
return (
<div style={{ marginTop: "10px" }}>
<span style={{ marginRight: "10px" }} className={cName}>
{count !== 0 ? count : zero}
</span>
<button
style={{ marginRight: "5px" }}
className="btn btn-secondary btn-sm"
onClick={increment}
>
+
</button>
<button
style={{ marginRight: "5px" }}
className="btn btn-secondary btn-sm"
onClick={decrement}
>
-
</button>
<button onClick={deleteHandler} className="btn btn-danger btn-sm">
Delete
</button>
</div>
);
}
export default Item;
项目列表代码 (parent)
function ItemList() {
const [items, setItems] = useState([Item, Item, Item]);
const deleteItem = (index) => {
alert(index);
var temp = [...items]; //create new copy
temp.splice(index, 1);
setItems(temp);
};
const resetAll = () => {
//this is where I need to call reset() on all the items (children)
};
return (
<div>
<div style={{ marginTop: "10px" }}>
<button className="btn btn-primary" onClick={resetAll}>
Reset
</button>
{items.map((MyItem, index) => {
return (
<div key={index}>
<MyItem deleteHandler={() => deleteItem(index)} />
</div>
);
})}
</div>
</div>
);
}
export default ItemList;
虽然您可以创建一个 React ref 并将它们转发给每个子组件,并实现 useImperativeHandle
挂钩,但这应该只是最后的手段。您可能会发现此 Fully uncontrolled component with a key 模式很有用。
它使用 React 键来重置组件,这实际上是 unmounts/mounts 一个新的“实例”。
添加一个额外的状态来保存 key
值,并在 resetAll
处理程序中更新此状态。我使用了一个随机值,但任何 GUID 生成器甚至一个简单的递增计数器都可以工作,关键部分是使用了新的 React 键值。
function ItemList() {
const [items, setItems] = useState([Item, Item, Item]);
const [key, setKey] = useState(Math.random()); // <-- key state
const deleteItem = (index) => {
alert(index);
var temp = [...items]; //create new copy
temp.splice(index, 1);
setItems(temp);
};
const resetAll = () => {
setKey(Math.random()); // <-- update key state
};
return (
<div>
<div key={key} style={{ marginTop: "10px" }}> // <-- resets elements/components
<button className="btn btn-primary" onClick={resetAll}>
Reset
</button>
{items.map((MyItem, index) => {
return (
<div key={index}>
<MyItem deleteHandler={() => deleteItem(index)} />
</div>
);
})}
</div>
</div>
);
}
这就是我现在拥有的。
除重置按钮外的每一行都是一个名为 Item
的 child 组件。一个项目有一个指示其计数的徽章,2 个用于递增、递减的按钮和一个 delete
按钮。名为 ItemList
的 parent 组件包含重置按钮和 children。由于 parent 维护 children 列表,因此删除功能也在 parent 中实现。除了 reset
按钮外,我需要的所有功能都已完成。
重置按钮可以被认为是一个主按钮,点击后应该能够重置所有 children 的 count
。计数由每个 child 保持为状态,因此理想情况下 parent 应该调用它包含在列表中的每个 child 的重置函数,但我无法为此提供代码特定部分。我不确定如何访问每个 child 的重置功能并将其应用于列表中的所有 children。
项目代码 (child)
function Item({ deleteHandler }) {
const [count, setCount] = useState(0);
const [cName, setCName] = useState("badge bg-warning text-dark");
useEffect(() => {
setCName(count !== 0 ? "badge bg-primary" : "badge bg-warning text-dark");
}, [count]);
const increment = () => {
setCount((prevCount) => prevCount + 1);
};
const decrement = () => {
setCount((prevCount) => prevCount - 1);
};
//this is what needs to be called
const reset = () => {
setCount(0);
};
const zero = "zero";
return (
<div style={{ marginTop: "10px" }}>
<span style={{ marginRight: "10px" }} className={cName}>
{count !== 0 ? count : zero}
</span>
<button
style={{ marginRight: "5px" }}
className="btn btn-secondary btn-sm"
onClick={increment}
>
+
</button>
<button
style={{ marginRight: "5px" }}
className="btn btn-secondary btn-sm"
onClick={decrement}
>
-
</button>
<button onClick={deleteHandler} className="btn btn-danger btn-sm">
Delete
</button>
</div>
);
}
export default Item;
项目列表代码 (parent)
function ItemList() {
const [items, setItems] = useState([Item, Item, Item]);
const deleteItem = (index) => {
alert(index);
var temp = [...items]; //create new copy
temp.splice(index, 1);
setItems(temp);
};
const resetAll = () => {
//this is where I need to call reset() on all the items (children)
};
return (
<div>
<div style={{ marginTop: "10px" }}>
<button className="btn btn-primary" onClick={resetAll}>
Reset
</button>
{items.map((MyItem, index) => {
return (
<div key={index}>
<MyItem deleteHandler={() => deleteItem(index)} />
</div>
);
})}
</div>
</div>
);
}
export default ItemList;
虽然您可以创建一个 React ref 并将它们转发给每个子组件,并实现 useImperativeHandle
挂钩,但这应该只是最后的手段。您可能会发现此 Fully uncontrolled component with a key 模式很有用。
它使用 React 键来重置组件,这实际上是 unmounts/mounts 一个新的“实例”。
添加一个额外的状态来保存 key
值,并在 resetAll
处理程序中更新此状态。我使用了一个随机值,但任何 GUID 生成器甚至一个简单的递增计数器都可以工作,关键部分是使用了新的 React 键值。
function ItemList() {
const [items, setItems] = useState([Item, Item, Item]);
const [key, setKey] = useState(Math.random()); // <-- key state
const deleteItem = (index) => {
alert(index);
var temp = [...items]; //create new copy
temp.splice(index, 1);
setItems(temp);
};
const resetAll = () => {
setKey(Math.random()); // <-- update key state
};
return (
<div>
<div key={key} style={{ marginTop: "10px" }}> // <-- resets elements/components
<button className="btn btn-primary" onClick={resetAll}>
Reset
</button>
{items.map((MyItem, index) => {
return (
<div key={index}>
<MyItem deleteHandler={() => deleteItem(index)} />
</div>
);
})}
</div>
</div>
);
}