這篇文章中的技巧和方法是我個人的喜好,僅供參考。
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 }))
}
}), []);
對象中的屬性都是可以被緩存的