我正在提取带有onRes
参数的自定义挂钩;
function useApi(onRes) {
useEffect(() => {
api().then((res) => {
onRes && onRes(res);
});
}, [onRes]);
}
使用此钩子:
import useApi from './useApi';
function App() {
const [x, setX] = useState(0);
useApi({
onRes: () => {}
})
return (
<div onClick={() => setX(Math.random())}>{x}</div>
)
}
请注意,每次<App/>
进行渲染时,onRes都会更改,并且useApi挂钩将再次运行
我的问题是应该用onRes
包装useCallback
吗?还是我只是通知钩子用户注意这个onRes
参数?
function useApi(onRes) {
const onResCb = useCallback(onRes, []); // should I do this ?
useEffect(() => {
api().then((res) => {
onResCb && onResCb(res);
});
}, [onResCb]);
}
答案 0 :(得分:0)
此博客文章可能有用:https://kentcdodds.com/blog/usememo-and-usecallback
我认为在这里使用回调是不相关的,因为您没有进行繁重的计算。实际上,useCallback
的性能要比按原样使用该函数低。
此外,如果onRes
未定义,则可以保存API调用。
function useApi(onRes) {
useEffect(() => {
if(! onRes){
return
}
api().then(onRes);
}, [onRes]);
}
答案 1 :(得分:0)
只需从onRes
的依赖项数组中删除useEffect
,这将确保效果仅在安装时运行
function useApi(onRes) {
useEffect(() => {
api().then((res) => {
onRes && onRes(res);
});
}, []);
}
第二个选项,使用空的依赖项数组定义通过useCallback
传递的函数,并将其传递给useApi
并保持当前的钩子不变
const onRes = useCallback(() => {
console.log('hi')
}, []);
useApi(onRes);
答案 2 :(得分:0)
阅读本文Refs to the Rescue!之后,我终于受到启发。
我们可以将onRes
与参考一起存储,并在需要时调用它。
function useApi(onRes) {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = onRes;
});
useEffect(() => {
api().then((res) => {
savedCallback.current && savedCallback.current(res);
});
}, []);
}