編寫React Hooks的5個建議

這篇文章中的技巧和方法是我個人的喜好,僅供參考。

effect的函數的名字

如果一個組件中多個effect,傳入的函數都沒有名字,這樣不好區分

const MyComp = () => {
  useEffect(() => {
    ...
  });
  useEffect(() => {
    ...
  });
  useEffect(() => {
    ...
  });
}

使用命名函數可以提示你方法的作用

const MyComp = () => {
  useEffect(function fetchData() {
    ...
  });
  useEffect(function subscribeToUpdates() {
    ...
  });
  useEffect(function useInterval() {
    ...
  });
}

還有另一個好處是你可以在React開發工具中看到命名的函數:
在這裏插入圖片描述

更加優雅的寫法,只要你喜歡

const MyComp = () => {
  function fetchData() {...}
  function subscribeToUpdates() {...}
  function useInterval() {...}

  useEffect(fetchData);
  useEffect(subscribeToUpdates);
  useEffect(useInterval);
}

異步函數

effect函數不支持異步功能(您不能返回promise)。太煩人了,讓我們嘗試解決它:

const MyComp = () => {
  useEffect(() => {(async() => {
    ...
  })();});
}

上面這樣寫是錯的,我們可以通過閉包,嘗試下面這樣的寫法

const MyComp = () => {
  async function fetchData() {...}
  useEffect(() => {
    fetchData();
  });
}

如果你不理解,可以這樣寫也是一樣的

const MyComp = () => {
  useEffect(function doSomething() {
    async function doSomethingAsync() {
    }
    doSomethingAsync();
  });
}

你可以吧effect的依賴傳遞給函數

async function doSomethingAsync(dep1, dep2) {
  ...
}

const MyComp = () => {
  useEffect(function doSomething() {
    doSomethingAsync(dep1, dep2);
  }, [dep1, dep2]);
}

防抖函數

封裝自己的防抖函數

const MyComp = () => {
  useEffect(function doSomethingDebounced() {
    const timeout = setTimeout(() => {
      doSomethingWith(value);
    }, 500);
    return () => clearTimeout(timeout);
  }, [value]);
}

這是防抖的實現,除了清除定時器外,沒有什麼功能。

useCallbacks

您可能會認爲在管理複雜對象時,useReducer優於useState:

function reducer(state, action) {
  switch(action.type) {
    case 'MOVE_RIGHT':
      return { ...state, left: state.left + action.step };
    case 'MOVE_DOWN':
      return { ...state, top: state.top + action.step };
    default:
      return state;
  }
}
const [position, dispatch] = useReducer(reducer, { left: 0, top: 0 });

但是考慮一下,如果您想要一個穩定的引用,仍然必須使用useCallback派發每個操作:

const moveRight = useCallback((step) => dispatch({ type: 'MOVE_RIGHT', step }), []);

除了上面這種寫法,下面這種寫法也許會更好

const [position, setPosition] = useState({ left: 0, top: 0 });
const actions = useMemo(() => ({
  moveRight: step => {
    setPosition(state => ({ ...state, left: state.left + step }))
  },
  moveDown: step => {
    setPosition(state => ({ ...state, top: state.top + step }))
  }
}), []);

對象中的屬性都是可以被緩存的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章