如何仅在 React 自定义挂钩中获取数据一次?

Posted

技术标签:

【中文标题】如何仅在 React 自定义挂钩中获取数据一次?【英文标题】:How do I fetch data in a React custom hook only once? 【发布时间】:2020-04-21 13:07:17 【问题描述】:

我有一个自定义钩子,它可以获取 许多 组件使用的本地 JSON 文件。

hooks.js

export function useContent(lang) 
    const [content, setContent] = useState(null);

    useEffect(() => 
        const abortController = new AbortController();
        const signal = abortController.signal;

        fetch(`/locale/$lang.json`,  signal: signal )
            .then((res) => 
                return res.json();
            )
            .then((json) => 
                setContent(json);
            )
            .catch((error) => 
                console.log(error);
            );

        return () => 
            abortController.abort();
        ;
    , [lang]);

    return  content ;

/components/MyComponent/MyComponent.js

import  useContent  from '../../hooks.js';

function MyComponent(props) 
  const  content  = useContent('en');

/components/MyOtherComponent/MyOtherComponent.js

import  useContent  from '../../hooks.js';

function MyOtherComponent(props) 
  const  content  = useContent('en');

我的组件行为相同,因为我在两者中都将相同的en 字符串发送到我的useContent() 挂钩。 useEffect() 应该仅在 lang 参数更改时运行,因此看到两个组件使用相同的 en 字符串,useEffect() 应该只运行一次 ,但它没有 - 它运行多次。这是为什么?如何更新我的钩子,使其仅在 lang 参数更改时获取?

【问题讨论】:

鉴于这似乎是一个共享状态,你为什么不使用上下文? 【参考方案1】:

钩子在不同的组件中独立运行(以及在相同组件类型的不同实例中)。所以每次在新组件中调用useContent,效果(获取数据)都会运行一次。 (正如 React 所承诺的那样,同一组件的重复渲染不会重新获取数据。)相关:React Custom Hooks fetch data globally and share across components?

在许多组件之间共享状态的通用 React 方法是使用 Context 挂钩 (useContext)。更多关于上下文here。你会想要这样的东西:

const ContentContext = React.createContext(null)

function App(props) 
  const  content  = useContent(props.lang /* 'en' */);
  return (
    <ContentContext.Provider value=content>
      <MyComponent>
      <MyOtherComponent>
  );


function MyComponent(props) 
  const content = useContext(ContentContext);


function MyOtherComponent(props) 
  const content = useContext(ContentContext);

这样,如果您想更新内容/语言/其他内容,您可以在应用级别(或您认为有意义的任何更高级别)执行此操作。

【讨论】:

以上是关于如何仅在 React 自定义挂钩中获取数据一次?的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义挂钩上使用 useCallback?

如何从自定义反应挂钩访问数据

使用 react 定期运行 fetch

如何在reactjs挂钩中创建自定义挂钩?

关闭模式后刷新使用自定义挂钩获取的数据

useRequest 函数中的数据可能为 null/未定义 - Typescript、React