【问题标题】:Check which dependency in useEffect was updated检查 useEffect 中的哪个依赖项已更新
【发布时间】:2020-01-10 14:28:38
【问题描述】:

我有这个useEffect 钩子:

useEffect(() => {
  setTop(t => t + (controller.position.y * tileSize))
  setLeft(l => l + (controller.position.x * tileSize))
}, [controller.position])

我希望它仅在 position 更改时才进行添加。如果tileSize 发生变化,我只想让它进行乘法运算。

我尝试将它放在两个 useEffect 中,但随后我收到了 React Hook useEffect has missing dependencies 警告:

useEffect(() => {
    setTop(t => t + (controller.position.y * spriteSize))
    setLeft(l => l + (controller.position.x * spriteSize))
}, [controller.position])

useEffect(() => {
    setTop((controller.position.y * spriteSize))
    setLeft((controller.position.x * spriteSize))
}, [spriteSize])

在这种情况下,最佳做法是什么?

编辑:

一个可重现的例子:

const [tileSize, setTileSize] = useState(0)
const controller = {
    position: {
        x: 0,
        y: 0
    }
}
useEffect(() => {
    setTop(t => t + (controller.position.y * tileSize))
    setLeft(l => l + (controller.position.x * tileSize))
}, [controller.position])

useEffect(() => {
    setTop((controller.position.y * tileSize))
    setLeft((controller.position.x * tileSize))
}, [tileSize])

const asdf = () => {
    setTileSize(150)
}

return (
    <div onClick={() => asdf()}>click me</div>
)

警告信息:

第 31 行:React Hook useEffect 缺少依赖项:'tileSize'。包括它或删除依赖数组。如果 'setTop' 需要 'tileSize' react-hooks/exhaustive-deps 的当前值,你也可以用 useReducer 替换多个 useState 变量

第 36 行:React Hook useEffect 缺少依赖项:'controller.position.x' 和 'controller.position.y'。要么包含它们,要么删除依赖数组 react-hooks/exhaustive-deps 第 46 行:无法访问的代码 no-unreachable

【问题讨论】:

  • 你在第二个useEffect钩子上设置了[tileSize]吗?
  • @Deda 是的,所以它会在useEffect 钩子之一中抱怨position,然后在另一个钩子中抱怨tileSize
  • 请展示整个代码/可重现的例子
  • @DennisVash 已更新。这两个变量都来自上下文 API 挂钩。你也需要吗?
  • @DennisVash:添加了一个可重现的示例

标签: reactjs use-effect


【解决方案1】:

有很多方法,您应该查看最适合您的用例的可读性。

  1. 如警告所示,替换为useReducer

React Hook useEffect 缺少一个依赖项:'tileSize'。包括它或删除依赖数组。如果“setTop”需要“tileSize”的当前值,您也可以用 useReducer 替换多个 useState 变量。 (react-hooks/exhaustive-deps)

const STATE = {
  ADDITION: 'addition',
  MULTIPLICATION: 'multiplication'
};

function reducer(state, action) {
  switch (action.type) {
    case STATE.ADDITION:
      return {
        ...state,
        position: action.position,
        top: state.top + action.position * state.spriteSize
      };
    case STATE.MULTIPLICATION:
      return {
        ...state,
        spriteSize: action.spriteSize,
        top: state.position * action.spriteSize
      };
    default:
      throw new Error();
  }
}

function Controller({ position, spriteSize }) {
  const [state, dispatch] = useReducer(reducer, {
    top: 0,
    position,
    spriteSize
  });

  useEffect(() => {
    dispatch({ type: STATE.ADDITION, position });
  }, [position]);

  useEffect(() => {
    dispatch({ type: STATE.MULTIPLICATION, spriteSize });
  }, [spriteSize]);

  return <FlexBox>{state.top}</FlexBox>;
}
  1. 您可以使用引用 useRef 并与旧值进行比较
  2. 如果您知道自己在做什么,只需禁用 lint 警告即可。

【讨论】:

  • 正是我想要的。很好的答案。
猜你喜欢
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
  • 2016-11-25
  • 2022-08-21
  • 2021-09-29
相关资源
最近更新 更多