簡體   English   中英

更新 state 時反應組件重新渲染

[英]React component re-renders when updating state

我正在處理具有多個步驟的頁面,基於當前步驟(由useState跟蹤),它呈現不同的組件。

我有一個父組件 ( App.js ),它跟蹤所有數據更改,每個步驟都在它自己的組件中。 在 Step 組件中,我注意到每當我選擇 select 時,都會發生重新渲染並且選擇丟失。 (由Step1.js中組件頂部的 console.log 觀察到)

如何確保不會發生重新渲染,以便正確跟蹤選擇?

應用程序.js

import React, { useState } from "react";
import { Button, Space } from "antd";

import Step1 from "./Step1";

import "antd/dist/antd.css";

const Step2 = () => {
  console.log("Rendering Step 2");
  return (
    <div>
      <b>Step 2</b>
    </div>
  );
};

const Step3 = () => {
  console.log("Rendering Step 3");
  return (
    <div>
      <b>Step 3</b>
    </div>
  );
};

export default () => {
  const [step, setStep] = useState(0);
  const [items, setItems] = useState({});

  const next = () => {
    setStep(step + 1);
  };

  const prev = () => {
    setStep(step - 1);
  };

  React.useEffect(() => {
    console.log("Items:", items);
  }, [items]);

  const updateItem = (key, value) => {
    setItems({
      [key]: value
    });
  };

  const stepProps = {
    updateItem: updateItem
  };

  const StepContent = props => {
    switch (step) {
      case 0:
        return <Step1 {...props} />;
      case 1:
        return <Step2 {...props} />;
      case 2:
        return <Step3 {...props} />;
      default:
        return <b>Error</b>;
    }
  };

  const StepBar = () => {
    return (
      <div>
        <Space>
          {step > 0 && (
            <Button
              size="large"
              onClick={() => prev()}
              style={{ minWidth: "100px" }}
            >
              Previous
            </Button>
          )}
          {step < 2 && (
            <Button
              size="large"
              onClick={() => next()}
              style={{ minWidth: "100px" }}
              block
            >
              Next
            </Button>
          )}
        </Space>
      </div>
    );
  };

  return (
    <div className="App">
      <StepContent {...stepProps} />
      <StepBar />
    </div>
  );
};

Step1.js

import React from "react";
import { Radio } from "antd";

const Step1 = ({ updateItem }) => {
  console.log("Rendering Step 1");

  const onChange = event => {
    const value = event.target.value;
    updateItem("option", value);
  };

  return (
    <div>
      <Radio.Group onChange={onChange}>
        <Radio value={"a"}>A</Radio>
        <Radio value={"b"}>B</Radio>
      </Radio.Group>
    </div>
  );
};

export default Step1;

Codesandbox 示例: https://codesandbox.io/s/stoic-cartwright-sr8ur

似乎您沒有在Radio.Group中傳遞實際值,因此您沒有得到它的實際值。

stepProps中添加items

const stepProps = {
    updateItem,
    items
  };

在您的Page1.js中,在您的解構道具中添加items ,並向Radio.Group添加一個 value 道具,如下所示:

const Step1 = ({ items, updateItem }) => {
  console.log("Rendering Step 1");

  const onChange = event => {
    const value = event.target.value;
    updateItem("option", value);
  };

  return (
    <div>
      <Radio.Group value={items["option"] || null} onChange={onChange}>
        <Radio value={"a"}>A</Radio>
        <Radio value={"b"}>B</Radio>
      </Radio.Group>
    </div>
  );
};

如果您還將其他步驟分開放在單獨的文件中以避免混淆,那會更好。

這是我的沙盒

我通過登錄來檢查這些值

StepContent= ...

無論我通過前進和后退檢查的步驟如何,值都會被保存,因為每次啟動此方法時,日志都會顯示 state沒有顯示在單選組中選擇的值,您需要將 state 傳遞給單選組的道具,以顯示選中的按鈕

僅當組件的 state 發生更改時才能觸發重新渲染。默認情況下, shouldComponentUpdate返回true

function shouldComponentUpdate(nextProps, nextState) {
        return true;
    }

這就是導致“一直更新所有內容”的原因。當 React 渲染組件時,它將運行shouldComponentUpdate並查看它是否返回 true。當您使用shouldComponentUpdate時,您需要確定哪些數據位實際上對 re-使成為。

shouldComponentUpdate(nextProps) {
        return nextProps.id !== this.props.id;
    }

暫無
暫無

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

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