简体   繁体   English

父组件在子组件列表中调用子组件 function

[英]Parent component to call child component function on a list of children component

This is what I have right now.这就是我现在所拥有的。

在此处输入图像描述

Each row excluding reset button is a child component called Item .除重置按钮外的每一行都是一个名为Item的子组件。 An item has a badge indicating its count, 2 buttons for increment, decrement & a delete button.一个项目有一个指示其计数的徽章,2 个用于递增、递减和delete按钮的按钮。 The parent component called ItemList contains the reset button & the children.名为ItemList的父组件包含重置按钮和子组件。 Since, the parent maintains list of children so delete functionality is also implemented in parent.因为,父级维护子级列表,所以删除功能也在父级中实现。 All my required functionality is complete except for the reset button.除了reset按钮外,我所有需要的功能都已完成。

The reset button can be considered as a master button & should be able to reset the count of all children when clicked.重置按钮可以被认为是一个主按钮,点击时应该能够重置所有孩子的count Count is maintained as state by each child so ideally the parent should be calling the reset function of each child it contains in the list but I am unable to come up with a code for this particular portion.每个孩子都将计数保持为 state,因此理想情况下,父母应该调用列表中包含的每个孩子的重置 function,但我无法为这个特定部分提供代码。 I am not sure how I can access the reset function of each child and apply it to all the children in the list.我不确定如何访问每个孩子的重置 function 并将其应用于列表中的所有孩子。

Code for Item (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;

Code for ItemList (parent) ItemList 的代码(父级)

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;

While you could create a React ref and forward them to each child component, and implement the useImperativeHandle hook, this should only be a last resort.虽然您可以创建一个 React ref 并将它们转发给每个子组件,并实现useImperativeHandle挂钩,但这应该只是最后的手段。 You may find this Fully uncontrolled component with a key pattern useful.您可能会发现这个具有键模式的完全不受控制的组件很有用。

It uses a React key to reset a component, which essentially unmounts/mounts a new "instance" to work with.它使用一个 React 键来重置一个组件,这实际上是卸载/安装一个新的“实例”来使用。

Add an additional piece of state to hold a key value, and update this state in the resetAll handler.添加一个额外的 state 来保存一个key ,并在resetAll处理程序中更新这个 state。 I've used a random value, but any GUID generator or even a simple incremented counter would work, the key part being that a new React key value is used.我使用了一个随机值,但任何 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>
  );
}

编辑子组件列表中的父组件调用子组件函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM