检查useEffect中的哪个依赖项已更新

时间:2019-09-08 16:04:10

标签: reactjs use-effect

我有这个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行:无法访问的代码无法访问

1 个答案:

答案 0 :(得分:1)

有很多方法,对于您的用例,您应该查看最易读的方法。

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

反应挂钩useEffect缺少依赖项:'tileSize'。包括它或删除依赖项数组。如果“ setTop”需要当前值“ tileSize”,也可以用useReducer替换多个useState变量。 (反应钩/详尽的下降)

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. 如果您知道自己在做什么,只需禁用棉绒警告。

Edit styled-antd-react-starter