如何在 React 自定义挂钩中仅获取一次数据?
How do I fetch data in a React custom hook only once?
我有一个自定义挂钩,可以获取 许多 组件使用的本地 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()
挂钩。当 lang
参数更改时,useEffect()
应该 仅 运行,因此鉴于两个组件使用相同的 en
字符串,useEffect()
应该只 运行 一次 ,但它不会 - 它 运行 多次。这是为什么?如何更新我的挂钩,使其仅在 lang
参数更改时获取?
挂钩 运行 独立于不同的组件(以及同一组件类型的不同实例)。所以每次在新的组件中调用useContent
,效果(取数据)都是运行一次。 (正如 React 所承诺的那样,重复渲染同一组件将不会重新获取数据。)相关:React Custom Hooks fetch data globally and share across components?
在许多组件之间共享状态的通用 React 方法是使用 Context hook (useContext
). More on contexts 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);
}
通过这种方式,如果您想更新内容/语言/其他任何内容,您可以在应用级别(或您认为有意义的任何更高级别)执行此操作。
我有一个自定义挂钩,可以获取 许多 组件使用的本地 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()
挂钩。当 lang
参数更改时,useEffect()
应该 仅 运行,因此鉴于两个组件使用相同的 en
字符串,useEffect()
应该只 运行 一次 ,但它不会 - 它 运行 多次。这是为什么?如何更新我的挂钩,使其仅在 lang
参数更改时获取?
挂钩 运行 独立于不同的组件(以及同一组件类型的不同实例)。所以每次在新的组件中调用useContent
,效果(取数据)都是运行一次。 (正如 React 所承诺的那样,重复渲染同一组件将不会重新获取数据。)相关:React Custom Hooks fetch data globally and share across components?
在许多组件之间共享状态的通用 React 方法是使用 Context hook (useContext
). More on contexts 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);
}
通过这种方式,如果您想更新内容/语言/其他任何内容,您可以在应用级别(或您认为有意义的任何更高级别)执行此操作。