代码之家  ›  专栏  ›  技术社区  ›  Zoltan Hernyak

React useEffect-在组件中还是在服务中?

  •  1
  • Zoltan Hernyak  · 技术社区  · 5 月前

    我们的组件有一个钩子(服务),它有一个 init() 和一个 shutdown() 功能(出于某种原因)。这个 init() 应至少调用一次以启动(开始心跳操作),并且 shutdown() 停止心跳。

    export default function EditProductForm({formToBeModify}: IEditProductClientFormProps): ReactNode {
      const service = useEditProductService();
    
      useEffect(() => {
        service.init();
        return () => service.shutdown();
      }, []);
    
     return {
       <div ...>
     }
    )
    

    useEffect() 足够粘稠,因为它的依赖性是 [] 这意味着 init() 在调用 组件已安装 shutdown() 在调用 组件将卸载 .

    建议将逻辑插入到组件(.tsx)文件中,但所有内容都应进入服务代码中。在这种情况下,服务将以某种方式如下所示:

    export default function useEditProductService() {
    
       function init() { 
          ...
       }
    
       function shutdown() {
          ...
       }
    
       useEffect(() => {
            init();
            return () => shutdown();
          }, []);
    
      return {
         init,
         shutdown
      }
    }
    

    这对我来说并不清楚,因为组件多次重新呈现自己,每次调用服务都是通过 const service = useEditProductService(formToBeModify) 它的工作原理和 使用效果() 留在那里,在组件内部?

    我认为,如果它在服务之外,在组件本身中,它的工作方式与我上面描述的一样 init() shutdown() 被调用一次。如果它在服务内部,则在组件生命周期内会调用多次。你怎么认为?

    1 回复  |  直到 5 月前
        1
  •  2
  •   Drew Reese    5 月前

    这与直接在一个或多个组件中运行效果相同。所有React钩子在每个渲染循环中都会被调用,您的 useEditProductService 包括挂钩。它是 useEffect 钩子及其控制何时的依赖项 它的 回调被调用。

    自定义React钩子的主要目的是代码重用。

    而不是在使用“服务”的每个组件中编写以下内容

    function init() { 
      ...
    }
    
    function shutdown() {
      ...
    }
    
    useEffect(() => {
      init();
      return shutdown;
    }, []);
    

    您可以简单地使用 使用EditProductService 钩住它的位置。

    useEditProductService();
    
    • 您已经减少了需要编写的代码量
    • 代码更多 干燥
    • 如果需要更新逻辑,则只能在一个位置进行更新 而不是应用程序中使用的每个地方

    我通常保持“三条规则”,这意味着一旦我在代码库中的某个地方第三次编写了相同的代码/逻辑块,我就会将其重构为可重用的函数或React钩子等,因为它不再是一个一次性的代码单元。