首页 > 解决方案 > React:如果 prop 更改,则重新渲染组件

问题描述

我有一个问题,当我通过父组件更改道具值时,子组件没有重新渲染。

父组件:

import React, { useEffect, useState } from 'react';
import "./style.scss";

import DeviceButton from "../../buttons/deviceButton/deviceButton";

function Dashboard({ socket }) {
    const [activeButtons, setActiveButtons] = useState({desk: false, shelf: false});

    function toggleLight(type, id) {
        if(type && id) {
            var buttons = activeButtons;
            buttons.desk = true;
            setActiveButtons(buttons);
            console.log(activeButtons)
        }
    }

    return(
        <div className="view">
            <div className="devices">
                <div className="buttons">
                    <DeviceButton text="Desk" active={activeButtons.desk} type="device" id="desk" event={toggleLight} />
                    <DeviceButton text="Shelf" active={activeButtons.shelf} type="device" id="shelf" event={toggleLight} />
                </div>
            </div>
        </div>
    )
}

子组件:

import React, { useState, useEffect } from 'react';
import "./style.scss";

function DeviceButton(props) {
    useEffect(() => {
        // This is only executed during initialization.
        console.log(props.active);
    }, [props.active]);
    return(
        <button className={`device-button ${props.active == true ? "active" : ""}`}  onClick={() => props.event(props.type, props.id)}>
            <span className="text">{props.text}</span>
            <span className="status">Inactive</span>
        </button>
    )
}

export default DeviceButton;

当我单击 DeviceButton 时,将调用父组件的 toggleLight 函数。这会导致状态发生变化,并作为道具传递给子组件。不幸的是,子组件没有再次渲染,所以我可以使用新的 prop 值。不幸的是,useEffect 函数仅在组件初始化时执行。

标签: reactjscomponents

解决方案


问题是您正在改变当前状态对象,而不是设置新的状态对象。React在确定状态是否改变时依赖于检查引用相等性;改变对象不会被视为内存中的新对象,因此不会提示重新渲染。

解决此问题的一种快速方法是使用扩展运算符进行浅拷贝,这将创建一个新对象:

function toggleLight(type, id) {
  if(type && id) {
    var buttons = {...activeButtons};
    buttons.desk = true;
    setActiveButtons(buttons);
  }
}

推荐阅读