繁体   English   中英

state 更改后反应组件不会重新渲染

[英]The react component doesn't re-render after state change

我有一个 React 项目,其中在 useEffect 挂钩中有一个 eventListener,将显示事件的数据。 在第一次尝试时它运行良好,但是当另一个事件即将到来并且我更改了包含需要显示的元素的数组的 state 时,组件不会重新呈现。

应用程序.js

import React, { useEffect, useReducer, useState } from "react";

function App(){
    const [dataTableElements, setDataTableElements] = useState([]);

    const sendMessage = (message) => {
        window.opener.postMessage(message, '*');
    }

    const receiveMessage = (e) => {
        if (e.data.source === 'source') {
            if (e.data.type === 'SEND_DATA') {
                const message = e.data.message;
                createElements(message);
            }
        } else {
            return;
        };
    };

    const createElements = (data) => {
        var temp = Object.assign([], dataTableElements);
        temp = [];
        {Object.keys(data).forEach((value, index) => {
            temp.push(<MyComponent key={value + " " + index} data={data[value]} />)
        })}
        
        setDataTableElements(temp);
    }

    useEffect(() => {
        sendMessage(message_READY);
        window.addEventListener("message", receiveMessage, false);

        return () => window.removeEventListener("message", receiveMessage);

    }, []);

    return (
        <Layout className="mainLayout">
            <Header>
                <AppHeader />
            </Header>
            <Content>
                <div className="tablesContainer">
                    {dataTableElements}
                </div>
            </Content>
        </Layout>
    );
    
}

export default PopupWindow;

I think the source of your problem is your useEffect function runs only when your component renders for the first time so it assign a function to your eventListener but this function is always the same and with same parameters, so when ever the event is dispatched it will run the same function with same parameter and then set you state to the same value that was before so it considers it as the state hasn't changed, You have to watch for your function on your useEffect and put your function on useCallback hook to prevent无限循环

import React, { useEffect, useState } from "react";
import { useCallback } from "react";

function App(){
    const [dataTableElements, setDataTableElements] = useState([]);

    const sendMessage = (message) => {
        window.opener.postMessage(message, '*');
    }

    const receiveMessage = useCallback((e) => {
        if (e.data.source === 'source') {
            if (e.data.type === 'SEND_DATA') {
                const message = e.data.message;
                createElements(message);
            }
        } else {
            return;
        };
    },[]);

    const createElements = (data) => {
        var temp = Object.assign([], dataTableElements);
        temp = [];
        {Object.keys(data).forEach((value, index) => {
            temp.push(<MyComponent key={value + " " + index} data={data[value]} />)
        })}
        
        setDataTableElements(temp);
    }

    useEffect(() => {
        sendMessage(message_READY);
        window.removeEventListener("message", receiveMessage); //here to prevent creating mutilple event listeners for same event , I am remove any old event and creating a new one
        window.addEventListener("message", receiveMessage, false);

        return () => window.removeEventListener("message", receiveMessage);

    }, [receiveMessage]);

    return (
        <Layout className="mainLayout">
            <Header>
                <AppHeader />
            </Header>
            <Content>
                <div className="tablesContainer">
                    {dataTableElements}
                </div>
            </Content>
        </Layout>
    );
    
}

export default PopupWindow;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM