You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用useMemo后LoadedContent仍重复渲染,如何解决?

问题根源

你遇到的问题核心是:当切换到tab1时,LoadedContent组件被从DOM中卸载了。虽然你用useMemo缓存了JSX元素,但组件实例的生命周期由它是否挂载在DOM中决定——再次切回tab2时,组件会重新挂载,内部的请求逻辑自然会再次执行。useMemo只是缓存了JSX的描述对象,无法阻止组件的卸载和重新挂载。

解决方案

下面提供两种原生React的解决思路,都能实现只发起一次请求的需求:

方案1:通过样式控制显示/隐藏,不卸载组件

让两个组件始终挂载在DOM中,用display样式控制是否显示。这样LoadedContent只会挂载一次,内部请求也只会执行一次:

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

const TabsPage = (props) => {
    const [tab, setTab] = useState("tab1");
    
    return (
        <div>
            <SimpleContent style={{ display: tab === "tab1" ? 'block' : 'none' }} />
            <LoadedContent style={{ display: tab === "tab2" ? 'block' : 'none' }} />
        </div>
    )
}

export default TabsPage;

方案2:把请求逻辑提升到父组件,缓存数据

将数据请求的逻辑从LoadedContent移到父组件,用useEffect只请求一次,然后把数据传给子组件。这样不管子组件是否挂载,数据只会获取一次:

父组件修改:

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);
    const [isLoading, setIsLoading] = useState(true);

    // 仅在组件挂载时请求一次数据
    useEffect(() => {
        // 替换为你的实际请求逻辑
        fetch('/your-api-url')
            .then(res => res.json())
            .then(data => {
                setLoadedData(data);
                setIsLoading(false);
            })
            .catch(err => {
                console.error('请求失败:', err);
                setIsLoading(false);
            });
    }, []);

    return (
        <div>
            {tab === "tab1" ? (
                <SimpleContent />
            ) : (
                isLoading ? <div>加载中...</div> : <LoadedContent data={loadedData} />
            )}
        </div>
    )
}

export default TabsPage;

子组件LoadedContent修改:

去掉内部的请求逻辑,直接接收父组件传递的数据:

// loadedContent.jsx
const LoadedContent = ({ data }) => {
    // 直接渲染data内容
    return <div>{/* 你的数据渲染逻辑 */}</div>;
}

export default LoadedContent;
补充说明

如果你的项目依赖第三方库,也可以使用react-keep-alive这类专门处理组件状态保留的库,但上述两种方案基于原生React,无需额外依赖,足够解决你的需求。

内容的提问来源于stack exchange,提问作者Gerry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:51:13