簡體   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