当前位置: 首页 > 知识库问答 >
问题:

如何防止每次导入自定义钩子时调用customHook中的useEffect?

景哲
2023-03-14

我正在使用react js和socket编写聊天应用程序。io库。

我订阅事件形成服务器并发出一些事件的所有逻辑都写在自定义钩子的使用效果中。

然后我从这个自定义钩子返回我需要的所有数据,并在我需要的组件中重用它。但是,我意识到,每次我将此自定义钩子导入到外部组件时,都会调用在use效应中编写的逻辑。

如果我将所有逻辑放在useEffect之外,调用它的次数甚至比导入自定义钩子的次数还要多。

如果有可能,我该如何预防呢?

如果不可能,请您提出什么解决方案?我不想在这个应用程序中使用redux,我想把所有的东西都保存在这个定制的钩子组件中,只需要在需要的地方重用其中的数据。

我不能分享工作示例,因为没有服务器部分它就无法工作,所以这里有一个简单的codesandbox示例。您可以在控制台中看到它被渲染了两次。

https://codesandbox.io/s/custom-hook-bfc5j?file=/src/useChat.js

共有2个答案

钱经业
2023-03-14

如果您想一次性设置一些副作用,但同时在多个位置使用生成的数据,一种方法是使用上下文功能

// 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;
};

您可以期望钩子在

如果在提供者组件的非子代中使用钩子,则返回的值将是我们初始化上下文实例时使用的defaultValue

张高澹
2023-03-14

它呈现两次,因为您在应用程序中调用了两次useChat()(一次在app.js中,另一次在Text.js中),您可以做的是在应用程序中创建useChat组件的引用。js和pass作为文本的道具。比如:

一个pp.js

import React from "react";
import useChat from "./useChat";
import Text from "./Text";
import "./styles.css";

export default function App() {
  const myUseChat = useChat();
  const { printMessage } = myUseChat;

  return (
    <div className="App">
      <button onClick={printMessage}>Print</button>
      <Text myUseChat={myUseChat} />
    </div>
  );
}

文本js

import React from "react";
import useChat from "./useChat";
import "./styles.css";

export default function Text(props) {
  const { text } = props.myUseChat;

  return <div className="App">{text}</div>;
}
 类似资料:
  • 问题内容: 编写python模块时,是否有办法防止客户端代码两次将其导入?就像c / c ++头文件一样: 非常感谢! 问题答案: Python模块不会多次导入。仅运行两次导入将不会重新加载模块。如果要重新加载它,则必须使用该语句。这是一个演示 是单行的模块 这是多次导入尝试的屏幕记录。

  • 问题内容: 假设我希望能够在程序中任何地方每次引发异常时都能够记录到文件。我不想修改任何现有代码。 当然,可以将其概括为每次引发异常时都可以插入钩子。 以下代码是否被认为可以安全地执行此操作? 问题答案: 如果要记录 未捕获的 异常,只需使用sys.excepthook即可。 我不确定是否会记录 所有 引发的异常的价值,因为很多库会在内部为可能不关心的事情引发/捕获异常。

  • 我有一个组件,我在其中调用我的自定义钩子。 自定义钩子如下所示: 而我在其中使用的导致错误的组件是: 有什么想法吗?

  • 问题内容: 我正在使用和自定义字体选择器。我希望显示所有可用的字体,每种字体名称以其自己的字体显示。我目前使用大约500种字体。 提供此功能的的示例: 问题在于,使用此渲染器时,在程序执行过程中,对象将变得无响应。第一次单击组合框以显示列表时,加载列表需要花费几秒钟的时间。第二次单击时,列表立即显示。 如果有人评论这一行 ,组合框就可以了。 如何防止这种反应迟钝? 问题答案: 发生的是,组合的内部

  • 和其它版本控制系统一样,Git 能在特定的重要动作发生时触发自定义脚本。 有两组这样的钩子:客户端的和服务器端的。 客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 你可以随心所欲地运用这些钩子。 安装一个钩子 钩子都被存储在 Git 目录下的 hooks 子目录中。 也即绝大部分项目中的 .git/hooks 。 当你用 git init 初始

  • 如何在自定义钩子中创建组件,钩子保存组件的状态? 我的尝试基本上是正确的,但是拖放并没有像预期的那样工作。相反,滑块只会在单击时更改值。我认为问题在于,useState钩子在定义之外被调用。但是我们如何在钩子中创建一个组件,然后我需要在钩子的其余部分中处理该内部组件的状态? https://codesandbox.io/s/material-demo-milu3?file=/demo.js:0-3