我应该在组件中使用一个还是多个useEffect?

Vad*_*dim 17 reactjs react-hooks

我有一些副作用要应用,并且想知道如何组织它们:

  • 一次性使用
  • 或几种useEffects

在性能和体系结构方面有什么更好的选择?

Shu*_*tri 32

您需要遵循的模式取决于您的useCase。

首先,您可能遇到以下情况:在初始挂载期间需要添加事件侦听器,并在卸载时对其进行清理;而在另一种情况下,则需要清理特定的侦听器并在属性更改时重新添加。在这种情况下,使用两个不同的useEffect更好地将相关逻辑保持在一起,并具有性能优势

useEffect(() => {
   // adding event listeners on mount here
   return () => {
       // cleaning up the listeners here
   }
}, []);

useEffect(() => {
   // adding listeners everytime props.x changes
   return () => {
       // removing the listener when props.x changes
   }
}, [props.x])
Run Code Online (Sandbox Code Playgroud)

第二:在某些状态或道具在一组中发生更改时,可能需要触发API调用或其他副作用。在这种情况下,一个useEffect具有相关值进行监视的个人应该是一个好主意

useEffect(() => {
    // side effect here on change of any of props.x or stateY
}, [props.x, stateY])
Run Code Online (Sandbox Code Playgroud)

第三:第三种情况,当您需要对不同的值进行更改时采取不同的操作。在这种情况下,请将相关比较分为不同的useEffects

useEffect(() => {
   // some side-effect on change of props.x
}, [props.x])

useEffect(() => {
   // another side-effect on change of stateX or stateY 
}, [stateX, stateY])
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢你编写 useCase 的方式。 (84认同)
  • @computrius [是](https://reactjs.org/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns),`React 将应用组件使用的每个效果,在指定它们的顺序。 (5认同)
  • 正如下面的答案所示,React 团队建议按关注点分离钩子,因此您可以将其拆分为多个“useEffect”调用。 (4认同)
  • 它们总是按照定义的顺序触发吗?即effect1总是先被调用,然后是effect2? (2认同)

Eri*_*rik 24

拥有多个 useEffect是完全可以的。

我的其中一项设置如下所示:

/*
 * Backend tags list have changed add the changes if needed
 */
useEffect(() => {
    setTagsList(setTagsAdded);
}, [setTagsAdded]);

/*
 * Backend files have changed add the changes if needed
 */
useEffect(() => {
    for (let i = 0; i < changedFilesMeta.length; i += 1) {
        // Is the list item value changed
        if (changedFilesMeta[i].id === currentEditableFile.id) {
            unstable_batchedUpdates(() => {
                setTags(changedFilesMeta[i].tags ? changedFilesMeta[i].tags : []);
            });
        }
    }
}, [changedFilesMeta]);

/*
 * Reset when user select new files using the filepicker
 */
useEffect(() => {
    if (setNewFiles.length > 0) {
        unstable_batchedUpdates(() => {
            setCurrentFile(null);
            setDescription('');
            setTitle('');
            setTags([]);
        });
    }
}, [setNewFiles]);

/*
 * User selecet to edit a file, change to that file
 */
useEffect(() => {
    // When user select a file to edit it
    if (currentEditableFile && currentEditableFile !== theCurrentFile) {
        setCurrentFile(currentEditableFile);
        unstable_batchedUpdates(() => {
            setDescription(currentEditableFile.description);
            setTitle(currentEditableFile.title);
            setTags(currentEditableFile.tags);
        });
    }
}, [currentEditableFile]);
Run Code Online (Sandbox Code Playgroud)

  • 我认为包含这段代码,尤其是脱离上下文,对这个问题没有帮助或相关。 (2认同)

小智 9

您应按照reactjs.org https://reactjs.org/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns的建议使用多种效果来分离关注点

  • 我知道,但如果您解释了为什么要进行关注点分离,以及这是否是架构概念或性能概念,那么您的答案将会更好。 (3认同)