Javascript 如何使用单击按钮的数据在从子组件网到父组件网的反应中启动setState函数

Javascript 如何使用单击按钮的数据在从子组件网到父组件网的反应中启动setState函数,javascript,reactjs,function,components,Javascript,Reactjs,Function,Components,我有一个名为FormLeadBuilderEdit的父组件网,我将setState(在我的例子中是setCards)函数向下传递给名为Card的子组件网,即useState钩子。由于某些原因,在子组件中,当我调用setCard(“vale”)时,状态不会更新。所以我不确定我做错了什么 任何帮助都会很好 谢谢 FormLeadBuilderEdit组件 import React, { useState, useEffect } from "react"; import { Ca

我有一个名为FormLeadBuilderEdit的父组件网,我将setState(在我的例子中是setCards)函数向下传递给名为Card的子组件网,即useState钩子。由于某些原因,在子组件中,当我调用setCard(“vale”)时,状态不会更新。所以我不确定我做错了什么

任何帮助都会很好

谢谢

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;
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>
    </>
  );
};
import React,{useState,useffect}来自“React”;
从“/Card”导入{Card};
const FormLeadBuilderEdit=({params})=>{
常量输入=[
{
输入类型:“短文本”,
uniId:Random.id(),
标签:“名字:”,
值:“Kanye”,
},
{
输入类型:“电话号码”,
uniId:Random.id(),
标签:“手机号码”,
值:“281334804”,
},
{
输入类型:“电子邮件”,
uniId:Random.id(),
标签:“工作电子邮件”,
值:“kanye@usa.gov",
},
{
输入类型:“地址”,
uniId:Random.id(),
标签:“家庭地址”,
价值:“白宫大道123号”,
},
{
输入类型:“MultipleChice”,
uniId:Random.id(),
标签:“首选联系方式”,
值:“281334804”,
多重回声:{
uniId:Random.id(),
选项:[
{
uniId:Random.id(),
标签:“电子邮件”,
勾选:假,
},
{
uniId:Random.id(),
标签:“手机”,
勾选:假,
},
],
},
},
{
输入类型:“下拉列表”,
uniId:Random.id(),
标签:“你是怎么找到我们的?”,
值:“281334804”,
下拉列表:{
uniId:Random.id(),
选项:[
{
uniId:Random.id(),
标签:“谷歌”,
},
{
uniId:Random.id(),
标签:“推荐”,
},
],
},
},
];
const[cards,setCards]=useState([]);
设置卡(输入)
返回(
);
};
导出默认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;
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>
    </>
  );
};
import React,{useRef}来自“React”;
从“meteor/Random”导入{Random};
导出常量卡=({setCards,cards})=>{
常量addOption=()=>{
const newCards=卡片;
newCards.map((卡片)=>{
如果(card.inputType==“多回音”){
card.multipleChoice.options.push({
uniId:Random.id(),
标签:“测试”,
勾选:假,
});
}
});
控制台日志(新卡);
设置卡(新卡);
返回(
添加选项
);
};

正如其中一位用户所指出的,您正在传递一个空的
数组,您正在该数组上执行
map
操作,该操作本身并不意外地返回一个空数组,因此您不会得到任何状态更改

传递
设置卡的逻辑正确

下面是一个小示例,其中状态正在发生变化,并显示


从“React”导入React,{useState};
常量应用=()=>{
const[cards,setCards]=useState([]);
返回(
{cards.toString()}

); }; 常量卡=({setCards,cards})=>{ 常量addOption=()=>{ 设置卡([“1”、“2”]); }; 返回( 添加选项 ); }; 导出默认应用程序;
截图:


React使用变量引用作为一种方式来知道哪些状态已更改,然后触发重新呈现

所以关于状态,您想知道的第一件事是“不要直接改变状态”。
参考:

相反,生成包含更改的新状态(具有不同的变量引用):

const addOption=()=>{
const newCards=cards.map((card)=>{
如果(card.inputType==“MultipleChice”){
常数newOption={
uniId:Random.id(),
标签:“测试”,
勾选:假,
};
card.multipleChoice.options=[…card.multipleChoice.options,newOption];
}
回程卡;
});
设置卡(新卡);

//setCards(cards);
map
返回新数组副本。尝试此
const newCard=…您的卡片映射代码;setCards(newCard)
根据您的逻辑,
cards.map
将始终返回一个空数组,您不需要添加任何选项。很抱歉,我的实际代码要大得多,因此我没有显示初始设置状态的位置。我已添加了我的修改,如上所述,它将控制台记录正确的(新卡)但是,如果没有可能的话,状态改变就不会重写页面,而是考虑在CODESANDBOX上发布这个项目并共享链接,我会尝试,但是它是一个流星项目,所以它有一些依赖关系,我不确定我可以设置,我遵循了你的模式,但是它控制台记录了未定义的,所以我修改了它在我上面的问题中看到的,但是我的状态CH。ange仍然没有重新呈现我的组件。我已经编辑了答案。我猜您希望触发选项数组的重新呈现。还请注意,
map
函数需要返回一些内容