简体   繁体   English

如何使用按钮单击中的数据从子组件到父组件触发 setState 函数

[英]How to fire a setState function in react from child componenet to parent componenet with data from a button click

I have a parent componenet called FormLeadBuilderEdit, and it is use useState hook I pass the setState(setCards in my case) function down to to my child componenet called Card.我有一个名为 FormLeadBuilderEdit 的父组件,它是 useState 钩子,我将 setState(在我的情况下为 setCards)函数传递给我的名为 Card 的子组件。 For some reason in the child componenet when I call setCard("vale") the state doesnt update.出于某种原因,当我调用 setCard("vale") 时,子组件中的状态不会更新。 So I am not sure what I am doing wrong.所以我不确定我做错了什么。

Any help would be great任何帮助都会很棒

Thanks谢谢

FormLeadBuilderEdit Component FormLeadBuilderEdit 组件

import React, { useState, useEffect } from "react";
import { Card } from "./Card";

const FormLeadBuilderEdit = ({ params }) => {

  const inputs = [
    {
      inputType: "shortText",
      uniId: Random.id(),
      label: "First Name:",
      value: "Kanye",
    },
    {
      inputType: "phoneNumber",
      uniId: Random.id(),
      label: "Cell Phone Number",
      value: "2813348004",
    },
    {
      inputType: "email",
      uniId: Random.id(),
      label: "Work Email",
      value: "kanye@usa.gov",
    },
    {
      inputType: "address",
      uniId: Random.id(),
      label: "Home Address",
      value: "123 White House Avenue",
    },
    {
      inputType: "multipleChoice",
      uniId: Random.id(),
      label: "Preferred Method of Contact",
      value: "2813348004",
      multipleChoice: {
        uniId: Random.id(),
        options: [
          {
            uniId: Random.id(),
            label: "Email",
            checked: false,
          },
          {
            uniId: Random.id(),
            label: "Cell Phone",
            checked: false,
          },
        ],
      },
    },
    {
      inputType: "dropDown",
      uniId: Random.id(),
      label: "How did you find us?",
      value: "2813348004",
      dropDown: {
        uniId: Random.id(),
        options: [
          {
            uniId: Random.id(),
            label: "Google",
          },
          {
            uniId: Random.id(),
            label: "Referral",
          },
        ],
      },
    },
  ];
  const [cards, setCards] = useState([]);

  setCards(inputs)

  return (
    <>
      <Card
        key={card.uniId + index}
        index={index}
        id={card.uniId}
        input={card}
        setCards={setCards}
        params={params}
        cards={cards}
      />
    </>
  );
};

export default FormLeadBuilderEdit;

Cart Component购物车组件

import React, { useRef } from "react";
import { Random } from "meteor/random";

export const Card = ({ setCards, cards }) => {
    const addOption = () => {
    const newCards = cards;

    newCards.map((card) => {
      if (card.inputType === "multipleChoice") {
        card.multipleChoice.options.push({
          uniId: Random.id(),
          label: "test",
          checked: false,
        });
      }
    });

    console.log(newCards);

    setCards(newCards);

  return (
    <>
      <button onClick={addOption} type="button">
        Add Option
      </button>
    </>
  );
};

As pointed out by one of the users, you are passing an empty cards array on which you are performing map operation which not surprisingly returns an empty array itself, hence you are not getting any state changes.正如其中一位用户所指出的,您正在传递一个空的cards数组,您正在该数组上执行map操作,这并不奇怪,它本身返回一个空数组,因此您没有得到任何状态更改。

The logic of passing the setCards is correct.传递setCards的逻辑是正确的。

Here is a small example where state changes are taking place and also showing.这是一个小示例,其中正在发生并显示状态更改。


import React, { useState } from "react";

const App = () => {
  const [cards, setCards] = useState([]);

  return (
    <>
      <Card
        setCards={setCards}
        cards={cards}
      />
      <p>{cards.toString()}</p>
    </>
  );
};



const Card = ({ setCards, cards }) => {
  const addOption = () => {
    setCards(["1","2"]);
  };

  return (
    <>
      <button onClick={addOption} type="button">
        Add Option
      </button>
    </>
  );
};

export default App;

Screenshot:截屏:

从子组件更改状态

Codesandbox Link 代码沙盒链接

React uses variable reference as a way to know which state has been changed and then triggers re-renders. React 使用变量引用来了解哪个状态已更改,然后触发重新渲染。

So one of the first thing you would like to know about state is that "Do not mutate state directly".所以你想知道的关于状态的第一件事就是“不要直接改变状态”。
Reference: https://reactjs.org/docs/state-and-lifecycle.html#using-state-correctly参考: https : //reactjs.org/docs/state-and-lifecycle.html#using-state-correctly

Instead, produce a new state that contains changes (which has different variable reference) :相反,生成一个包含更改的新状态(具有不同的变量引用):

const addOption = () => {
    const newCards = cards.map((card) => {
      if (card.inputType === "multipleChoice") {          
        const newOption = {
          uniId: Random.id(),
          label: "test",
          checked: false,
        };
        card.multipleChoice.options = [...card.multipleChoice.options, newOption];
      }
      return card;
    });

    setCards(newCards);
    // setCards(cards); <- this refer to the current `cards` which will not trigger re-render
  };

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

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