Reactjs 如何在React自定义钩子中只提取一次数据?

Reactjs 如何在React自定义钩子中只提取一次数据?,reactjs,react-hooks,fetch-api,use-effect,Reactjs,React Hooks,Fetch Api,Use Effect,我有一个定制的钩子,它获取许多组件使用的本地JSON文件 hooks.js export function useContent(lang) { const [content, setContent] = useState(null); useEffect(() => { const abortController = new AbortController(); const signal = abortController.signal;

我有一个定制的钩子,它获取许多组件使用的本地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 };
}
import { useContent } from '../../hooks.js';

function MyComponent(props) {
  const { content } = useContent('en');
}
import { useContent } from '../../hooks.js';

function MyOtherComponent(props) {
  const { content } = useContent('en');
}
/components/MyComponent/MyComponent.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 };
}
import { useContent } from '../../hooks.js';

function MyComponent(props) {
  const { content } = useContent('en');
}
import { useContent } from '../../hooks.js';

function MyOtherComponent(props) {
  const { content } = useContent('en');
}
/components/MyOtherComponent/MyOtherComponent.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 };
}
import { useContent } from '../../hooks.js';

function MyComponent(props) {
  const { content } = useContent('en');
}
import { useContent } from '../../hooks.js';

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

我的组件的行为相同,因为我将相同的
en
字符串发送到我的
useContent()
hook。
useffect()
应仅在
lang
参数更改时运行,因此鉴于两个组件使用相同的
en
字符串,因此
useffect()
应仅运行一次,但它不会运行—它会运行多次。为什么呢?如何更新钩子,使其仅在
lang
参数更改时获取?

钩子在不同组件(以及相同组件类型的不同实例)中独立运行。因此,每次在新组件中调用
useContent
,效果(获取数据)都会运行一次。(如React所承诺的,重复呈现相同组件将不会重新获取数据。)相关:

跨多个组件共享状态的一般方法是使用钩子(
useContext
)。更多关于上下文。您可能需要以下内容:

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);
}
const ContentContext=React.createContext(null)
功能应用程序(道具){
const{content}=useContent(props.lang/*'en'*/);
返回(
);
}
功能MyComponent(道具){
const content=useContext(ContentContext);
}
功能部件(道具){
const content=useContext(ContentContext);
}

这样,如果您想更新内容/语言/任何内容,您可以在应用程序级别(或您决定的任何更高级别)进行更新。

鉴于这似乎是一种共享状态,为什么不使用上下文?