簡體   English   中英

檢查useEffect中的哪個依賴項已更新

[英]Check which dependency in useEffect was updated

我有這個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

有很多方法,對於您的用例,您應該選擇最易讀的方法。

  1. 如警告所示,替換為useReducer

React Hook useEffect缺少依賴項:'tileSize'。 包括它或刪除依賴項數組。 如果“ setTop”需要當前值“ tileSize”,也可以用useReducer替換多個useState變量。 (反應鈎/詳盡-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. 如果您知道自己在做什么,只需禁用棉絨警告即可。

編輯樣式化的antd-react-starter

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM