【问题标题】:How to immediatelly update Parent state inside Child components如何立即更新子组件中的父状态
【发布时间】:2025-12-12 07:55:01
【问题描述】:

我正在尝试立即更新父组件的状态,以便可以在子(嵌套)组件中正确使用它。我会尽力提供尽可能多的细节,以便您理解。

所以基本上我有一个父组件(App.js):

import React, { useState } from "react";
import Child from "./Child";
import Modal from "./Modal";
import "./styles.css";

export default function App() {
  const [options, setOptions] = useState([
    { Player: "Kevin Durant", Team: "*lyn Nets" },
    { Player: "LeBron James", Team: "Los Angeles Lakers" },
    { Player: "Michael Jordan", Team: "Chicago Bulls" }
  ]);
  const [selectedOption, setSelectedOption] = useState({});
  const [modalContent, setModalContent] = useState(null);
  const [show, setShowModal] = useState(false);

  const showModal = () => {
    setShowModal(true);
  };

  const hideModal = () => {
    setShowModal(false);
  };
  return (
    <div className="App">
      <div
        className="row"
        style={{
          justifyContent: "center",
          width: "100%",
          margin: "40px 0px 0px 0px"
        }}
      >
        <div
          className="table-cell other"
          onClick={() => {
            setModalContent(() => (
              <Child
                options={options}
                selectedOption={selectedOption}
                setSelectedOption={setSelectedOption}
              />
            ));
            showModal();
          }}
        >
          <div className="table-cell-text">Click to access Child component</div>
        </div>
      </div>
      <Modal
        show={show}
        modalClosed={hideModal}
        width={"40%"}
        title={"Choose a Player"}
      >
        {modalContent}
      </Modal>
    </div>
  );
}

App.js父组件)视觉:

这个组件有一个对象数组(options)作为props发送到Child组件。

我提到的对象数组:

  [
    { Player: "Kevin Durant", Team: "*lyn Nets" },
    { Player: "LeBron James", Team: "Los Angeles Lakers" },
    { Player: "Michael Jordan", Team: "Chicago Bulls" }
  ]

基本上,子组件有一个模态组件和一个选择输入,它将显示选项。

Child.js

import React from "react";
import Team from "./Team";

const Child = (props) => {
  return (
    <div style={{ position: "relative", margin: "0 auto", width: "10em" }}>
      <div className="input-group col">
        <select
          className="form-control"
          onChange={(e) => {
            let foundOption = props.options.find(
              (options) => options.Player === e.target.value
            );
            props.setSelectedOption(foundOption);
          }}
        >
          <option value="">Select a Player...</option>
          {props.options.map((option) => (
            <option key={option.Player} value={option.Player}>
              {option.Player}
            </option>
          ))}
        </select>
      </div>
      <Team selectedOption={props.selectedOption} />
    </div>
  );
};

export default Child;

Child.js 视觉效果:

子组件也有一个团队组件。基本上 Team 组件接收 selectedOption 作为道具,并显示一个具有 selectedOption.Team 值的 div。

Team.js

import React from "react";

const Team = (props) => {
  console.log(props.selectedOption);
  return (
    <div style={{ marginTop: "30px" }}>
      Team:{" "}
      {props.selectedOption !== undefined ? props.selectedOption.Team : ""}
    </div>
  );
};

export default Team;

问题是,如果我选择一个选项,Team 组件不会立即收到更新的 selectedOption。所以,如果我想展示球员的球队,我需要选择一个选项,关闭模态并重新打开它。

我还录制了一个视频来说明这个问题:https://youtu.be/3P1tURgxvTQ

我想知道如何使它正常工作!如果你们不明白我的问题,请告诉我,我会努力改进。谢谢大家!

我的代码沙盒:

【问题讨论】:

  • 不使用useState 来控制modal 的内容以及它的可见性状态,只渲染modal 的内容(&lt;Child&gt;)并且只控制它的可见性。这样,当 props 发生变化时,内容就会更新。
  • @cbr 我该怎么做?

标签: javascript reactjs react-hooks state


【解决方案1】:

这将是您的App.js 文件:

import React, { useState } from "react";
import Child from "./Child";
import Modal from "./Modal";
import "./styles.css";

export default function App() {
  const [options, setOptions] = useState([
    { Player: "Kevin Durant", Team: "*lyn Nets" },
    { Player: "LeBron James", Team: "Los Angeles Lakers" },
    { Player: "Michael Jordan", Team: "Chicago Bulls" },
  ]);
  const [selectedOption, setSelectedOption] = useState(); // <--- remove the {} from here because your checking props.selectedOption !== undefined in Team Comp
  const [modalContent, setModalContent] = useState(false); // <--- the content state is now just a boolean
  const [show, setShowModal] = useState(false);

  const showModal = () => {
    setShowModal(true);
  };

  const hideModal = () => {
    setShowModal(false);
  };
  return (
    <div className="App">
      <div
        className="row"
        style={{
          justifyContent: "center",
          width: "100%",
          margin: "40px 0px 0px 0px",
        }}
      >
        <div
          className="table-cell other"
          onClick={() => {
            setModalContent(true);
            showModal();
          }}
        >
          <div className="table-cell-text">Click to access Child component</div>
        </div>
      </div>
      <Modal
        show={show}
        modalClosed={hideModal}
        width={"40%"}
        title={"Choose a Player"}
      >
        {modalContent && (
          <Child
            options={options}
            selectedOption={selectedOption}
            setSelectedOption={setSelectedOption}
          />
        )}
      </Modal>
    </div>
  );
}

这将是Child.js

import React from "react";
import Team from "./Team";

const Child = (props) => {
  return (
    <div style={{ position: "relative", margin: "0 auto", width: "10em" }}>
      <div className="input-group col">
        <select
          className="form-control"
          onChange={(e) => {
            let foundOption = props.options.find(
              (options) => options.Player === e.target.value
            );
            props.setSelectedOption(foundOption);
          }}
        >
          <option value="">Select a Player...</option>
          {props.options.map((option) => (
            <option key={option.Player} value={option.Player}>
              {option.Player}
            </option>
          ))}
        </select>
      </div>
      <Team selectedOption={props.selectedOption} />
    </div>
  );
};

export default Child;

这将是Team.js

import React from "react";

const Team = (props) => {
  console.log(props.selectedOption);
  return (
    <div style={{ marginTop: "30px" }}>
      Team:{" "}
      {props.selectedOption && props.selectedOption.Team || ""}
    </div>
  );
};

export default Team;

虽然我不太清楚为什么要将options 保留为状态,或者为什么需要在App.js 中使用selectedOption,但将其放在Child.js 中是有意义的

【讨论】:

  • 你好,塔吉!这是因为在我的项目中我使用了类似的布局,并且在 App.js 中我提交了一个表单(我使用 selectedOption 数据作为发布请求发送),这就是为什么我需要 selectedOption在 App.js 中
  • 谢谢你,塔吉!如果可能的话,我想借此机会问你另一个问题。我想知道它不起作用的理论原因
  • @Polalas 这样做的原因是您将 Child 组件设置为状态 (modalContent),而 modalContent stateChild Component and its props 仅在您单击父项时设置组件(当您打开模式时)。这就是为什么您必须关闭模式并再次打开它才能看到 Child 组件的新 props
最近更新 更多