簡體   English   中英

為什么將更新的 state 從子組件提升到父組件不起作用?

[英]Why lifting an updated state from a child to a parent component does not work?

在切換孩子的 state 后嘗試更新父組件的 UI 時,我設法達到了我想要的結果,但是,作為 React 初學者,我想我做得不太對。

正如您將在下面的代碼中看到的,我根據event.target.value更新了單選按鈕組件的 state,然后通過onToggle道具使用SitePageToggle ( WebsitePicker ) 將其提升到組件。 問題是,根據我的理解,我應該使用selectedRadioBtn及其更新的 state。但是,當我通過selectedRadioBtn以便我可以根據它來確定我的QAObject變量的 state 時,“網站”和“頁面”之間的切換順序' 被搞砸了和顛倒了。 如果我在子組件本身中使用更新的 state,這不是問題。

我知道[狀態更新可能是異步的][1],但是通過接受回調使用 useState 鈎子第二個版本也沒有解決問題。

這是父組件中的代碼:

import styles from "./WebsitePicker.module.css";
import { useState } from "react";
import SitePageToggle from "./SitePageToggle";
import SubmitButton from "./Buttons/SubmitButton";

function WebsitePicker() {
    const [QAObject, setQAObject] = useState("Website");
    const { label, input__url } = styles;

    const toggleWebsitePageHandler = toggleData => {
        if (toggleData === 'Website') {
            setQAObject("Website");
        } else {
            setQAObject("Page");
        }
    };

    return (
        <>
            <SitePageToggle onToggle={toggleWebsitePageHandler} />
            <form onSubmit={formSubmissionHandler}>
                <label className={label} htmlFor="picker">
                    Enter the URL of the {QAObject} you wish to QA.
                </label>
                <br />
                <input
                    id="picker"
                    type="url"
                    className={input__url}
                />
                <SubmitButton>QA my page</SubmitButton>
            </form>
        </>
    );
}

export default WebsitePicker;

這是子組件中的代碼:

import RadioButton from "./Buttons/RadioButton";

function SitePageToggle({ onToggle }) {
    const [selectedRadioBtn, setSelectedRadioBtn] = useState("Website");

    const isRadioSelected = (btnValue) => selectedRadioBtn === btnValue;

    const handleToggle = event => {
        setSelectedRadioBtn(event.target.value);
        onToggle(event.target.value);
    };

return (
    <ul>
        <li>
            <RadioButton
                label="Website"
                name="react-radio-btn"
                value="Website"
                checked={isRadioSelected("Website")}
                onChange={handleToggle}
            />
        </li>
        <li>
            <RadioButton
                label="Page"
                name="react-radio-btn"
                value="Page"
                checked={isRadioSelected("Page")}
                onChange={handleToggle}
            />
        </li>
    </ul>
);
}

export default SitePageToggle;


  [1]: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

不確定我是否完全理解用例,但如果目標是將selectedRadioBtn state提升到父級(而不是同步兩個狀態),那么SitePageToggle可能不需要保留 state 的單獨副本,而是從父母。

快速簡化演示: stackblitz

WebsitePicker QAObject作為selectedRadioBtn傳遞:

<SitePageToggle
  selectedRadioBtn={QAObject}
  onToggle={toggleWebsitePageHandler}
/>

SitePageToggle ,使用道具中的selectedRadioBtn作為 state:

import RadioButton from "./Buttons/RadioButton";

function SitePageToggle({ selectedRadioBtn, onToggle }) {
  const isRadioSelected = (btnValue) => selectedRadioBtn === btnValue;
  const handleToggle = (event) => {
    onToggle(event.target.value);
  };

  return (
    <ul>
      <li>
        <RadioButton
          label="Website"
          name="react-radio-btn"
          value="Website"
          checked={isRadioSelected("Website")}
          onChange={handleToggle}
        />
      </li>
      <li>
        <RadioButton
          label="Page"
          name="react-radio-btn"
          value="Page"
          checked={isRadioSelected("Page")}
          onChange={handleToggle}
        />
      </li>
    </ul>
  );
}

export default SitePageToggle;

要正確傳遞子項 state selectedRadioBtn ,您應該使用 useEffect()。 useEffect 的第二個參數是依賴數組,所以只要selectedRadioBtn發生變化,它就會觸發。

import RadioButton from "./Buttons/RadioButton";

function SitePageToggle({ onToggle }) {
    const [selectedRadioBtn, setSelectedRadioBtn] = useState("Website");

    const isRadioSelected = (btnValue) => selectedRadioBtn === btnValue;

    const handleToggle = event => {
        setSelectedRadioBtn(event.target.value);
        // onToggle(event.target.value); <-- delete this here
    };

    useEffect(() => {
        onToggle(selectedRadioBtn);
    }, [selectedRadioBtn]);

    return (
        <>...</>
    );
}

暫無
暫無

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

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