这篇文章中的技巧和方法是我个人的喜好,仅供参考。
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 }))
}
}), []);
对象中的属性都是可以被缓存的