UseMemo 仍在重新渲染组件

问题描述 投票:0回答:1

以下是我编写的组件的简化。它有两个选项卡,根据选择的选项卡显示不同的内容(通过此处未包含的按钮完成)。 有两个子组件,一个仅显示静态内容的 SimpleContent 对象,以及一个必须离开的 LoadedContent 组件,从服务器调用以获取数据,然后呈现自身。我想做的只是让该服务器调用一次,所以我不想每次选择该选项卡时都重新渲染 LoadedContent。我希望它渲染 LoadedContent 组件一次,即使我单击选项卡 1,然后返回选项卡 2。

我认为使用 UseMemo 来包装 LoadedContent 组件会起作用,但事实并非如此 - 每次我单击选项卡 2 时,它都会重新加载内容。请问我该如何解决这个问题?

import React, { useState, useMemo } from 'react';
import LoadedContent from './loadedContent';
import SimpleContent from './simpleContent';

const TabsPage = (props) => {

    const [tab, setTab] = useState("tab1");
    
    const tab2Display = useMemo(() => {
        return (
            <LoadedContent  />
        )
    }, [])

    return (
    
        <div>
            {tab === "tab1" ? 
                <SimpleContent />
            : 
                {tab2Display}
        </div>
    )
}

export default TabsPage;
reactjs react-hooks
1个回答
0
投票

为了确保 LoadedContent 组件只获取一次数据,您应该将加载逻辑移至父组件中,并将加载的数据存储在状态中。单独使用 useMemo 不会阻止重新渲染,因为它会在每次渲染时重新计算。以下是实现此方法的方法:

创建一个状态来保存加载的内容数据。 组件安装时使用效果来获取数据。 使用获取的数据渲染 LoadedContent。 这是 TabsPage 组件的更新版本:

import React, { useState, useEffect } from 'react';
import LoadedContent from './loadedContent';
import SimpleContent from './simpleContent';

const TabsPage = (props) => {
    const [tab, setTab] = useState("tab1");
    const [loadedData, setLoadedData] = useState(null);

    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await fetch('YOUR_API_ENDPOINT'); // Replace with your API endpoint
                const data = await response.json();
                setLoadedData(data);
            } catch (error) {
                console.error('Error fetching data:', error);
            }
        };

        // Fetch data only once when the component mounts
        if (!loadedData) {
            fetchData();
        }
    }, [loadedData]);

    return (
        <div>
            <button onClick={() => setTab("tab1")}>Tab 1</button>
            <button onClick={() => setTab("tab2")}>Tab 2</button>

            {tab === "tab1" ? 
                <SimpleContent />
                : 
                loadedData ? <LoadedContent data={loadedData} /> : <p>Loading...</p>
            }
        </div>
    );
}

export default TabsPage;

在我看来,更好的解决方案是使用

react-query
,但需要更多重构。它们有一个
useQuery
钩子,可以从端点获取数据,然后缓存结果,因此您可以非常明确地知道何时要重新获取数据。 如果您有兴趣,这里是文档

© www.soinside.com 2019 - 2024. All rights reserved.