簡體   English   中英

如何在子組件中立即更新父 state

[英]How to immediatelly update Parent state inside Child components

我正在嘗試立即更新父組件的 state 以便我可以在子(嵌套)組件中正確使用它。 我會盡量提供盡可能多的細節,以便您理解。

所以基本上我有一個父組件( 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: "Brooklyn 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: "Brooklyn Nets" },
    { Player: "LeBron James", Team: "Los Angeles Lakers" },
    { Player: "Michael Jordan", Team: "Chicago Bulls" }
  ]

基本上,子組件有一個模態組件和一個 select 輸入,它將顯示選項。

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視覺效果:

在此處輸入圖像描述

Child 組件也有一個 Team 組件。 基本上, Team組件接收 selectedOption 作為道具,並顯示一個具有 selectedOption.Team 值的 div。

團隊.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;

問題是,如果我選擇 select 選項,Team 組件不會立即收到更新的 selectedOption。 所以,如果我想顯示球員的隊伍,我需要 select 一個選項,關閉模態並重新打開它。

我還錄制了一段視頻來說明這個問題: https://youtu.be/3P1tURgxvTQ

我想知道我怎樣才能讓它正常工作,如果你們不明白我的問題。 請讓我知道,我會努力改進它。 謝謝你們!

我的代碼沙盒:

編輯optimistic-browser-870oe

這將是您的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: "Brooklyn 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保留為 state 或為什么需要在App.js中使用selectedOption ,但將其放在Child.js中是有意義的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM