reactjs - 如何防止每次导入自定义钩子时调用 customHook 中的 useEffect?
问题描述
我正在使用 react js 和 socket.io 库编写聊天应用程序。
我从服务器订阅事件并发出一些事件的所有逻辑都写在自定义钩子的 useEffect 中。
然后我从这个自定义钩子返回我需要的所有数据,并在我需要的组件中重用它。但是,我意识到每次将此自定义钩子导入外部组件时都会调用用 useEffect 编写的逻辑。
如果我将所有逻辑放在 useEffect 之外,它的调用次数甚至比导入自定义钩子的次数还要多。
如果可能的话,我该如何预防?
如果不可能,请您建议什么解决方案?我不想为这个应用程序使用 redux,我想把所有东西都保存在这个自定义钩子组件中,并在我需要的地方重用它的数据。
我不能分享工作示例,因为没有服务器部分它就无法工作,所以这里是一个简单的代码框示例。您可以在控制台中看到它被渲染了两次。
https://codesandbox.io/s/custom-hook-bfc5j?file=/src/useChat.js
解决方案
如果您想设置一些副作用一次但还要在多个地方使用结果数据,一种方法是使用上下文功能。
// ws/context.jsx, or similar
const WsContext = React.createContext(defaultValue);
export const WsProvider = props => {
const [value, setValue] = useState(someInitialValue);
useEffect(() => {
// do expensive things, call setValue with new results
});
return (
<WsContext.Provider value={value}>
{props.children}
</WsContext.Provider>
);
};
export const useCustomHook = () => {
const value = useContext(WsContext);
// perhaps do some other things specific to this hook usage
return value;
};
您可以期望钩子在任何作为<WsProvider>
React 渲染元素树的后代的组件中工作。
如果您在提供者组件的非后代中使用钩子,则返回的值将是defaultValue
我们初始化上下文实例的值。
推荐阅读
- jquery - 如何减少具有相同功能但事件不同的 Jquery 代码
- java - 使用 Logger 将堆栈跟踪写入文件产生空文件
- c# - c# - URL中的httpWebRequest授权问题
- binary-tree - n 个节点的二叉树的最大叶节点数和最小叶节点数是多少?
- python - 游戏结束后停止球动画的问题
- c# - 在 Unity 中加载序列化的精灵图标
- python - “列表索引必须是整数或切片,而不是 NoneType”错误
- python-3.x - 无法使用 BeautifulSoup 或请求打开 URL
- java - 如何创建“assets.bin”文件来保存和读取我的游戏的多个图像?
- azure-data-factory - 从 Http rest api 中提取数据,如何为 cookie 身份验证配置 http 请求头