【问题标题】:How can I use variables in useEffect without having them in a dependency?如何在 useEffect 中使用变量而不将它们放在依赖项中?
【发布时间】:2021-02-11 16:01:11
【问题描述】:

我有一个 objectList 和一个 size 变量。

const [objectList, setObjectList] = useState([]); //will be filled elsewhere
const [size, setSize] = useState([props.width, props.height]); //might change on user input

useEffect(() => {
    //When size changes iterate over objectList
    objectList.forEach(object => {
        object.set({
            width: size.width,
            height: size.height
        );
    });
}, [size]);

这里 React 抱怨说 objectList 没有依赖关系,因为它可能是,我想将 useEffect 依赖于 objectList 更改。然而我没有。偶尔可以将对象添加到列表中,但在这种情况下,我正在设置将对象添加到列表的大小。当我将新对象添加到列表(objectList 已更改)时,我不想迭代每个对象,只有在大小更改时才迭代。

如何在每次大小更改时迭代 objectList 而不是在 objectList 更改时迭代?

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    似乎有两个动作会影响objectList:大小更改和添加新对象时。您需要将这两者分开。

    您可以通过useReducer 来管理不同的操作。

    const initialState = {
      objectList: []
    }
    
    function reducer(state, action) {
      switch (action.type) {
        case 'ADD_OBJECT': /* TODO */ return;
        case 'UPDATE_SIZE': {
           const { size } = action.payload;
           return state.objectList.map((o) => ({
             ...o,
             width: size.width,
             height: size.height
           }))
        }
        default: /* TODO */;
      }
    }
    
    function App(props) {
      const [state, dispatch] = useReducer(reducer, initialState);
    
      useEffect(() => {
        dispatch({
          type: 'UPDATE_SIZE',
          payload: {
            size: {
              width: props.width,
              height: props.height
            }
          }
        });
      }, [props.size]);
    }
    

    【讨论】:

    • 嗯,如果我有一个 onSizeChanged 函数,即使不使用减速器,我也可以遍历 objectList,不是吗?但是,当我想要在 useEffect 函数中使用它时,它就行不通了。
    • 我刚刚看到你最近关于props.width等的更新。更新了。无论如何,如果父组件和子组件也更新了这些道具,则使用props.width 等作为初始状态是一种反模式。
    • 好的,这是可能的,但是有其他选择吗?我没有在我的应用程序中使用 useReducer。将整个应用程序更改为 useReducer 需要相当多的重构工作。我将示例提取得更抽象,因为我无法在此处发布整个应用程序代码。
    • 好吧,唯一的区别是如何更新objectList,它正在调度一个动作而不是通过setObjectList ,访问objectList只是添加state,就像state.objectList一样。考虑到只有两个影响objectList 的操作,我认为重构并不过分。如果是的话,我会闻到别的味道。
    • 我意识到 useReducer 可能是这里的最佳实践,我一直想重构为 useReducer,但是我想快速添加此功能,该应用程序需要大量返工,因为我在学习时正在编写它。它像现在一样工作,需要重构,但现在时间有限。这就是为什么我想看看我是否可以在这里使用 useEffect 。我现在有一个解决方法,我将 objectList 在本地放入 const objects,但是当我有时间清理和重构所有内容时会回到你的答案。因此,我检查答案是否正确。
    猜你喜欢
    • 1970-01-01
    • 2022-09-30
    • 2023-02-23
    • 2021-02-11
    • 2021-09-07
    • 2022-08-14
    • 2020-07-24
    • 2020-07-19
    • 1970-01-01
    相关资源
    最近更新 更多