反应钩子:使用回调函数参数提取钩子时的模式

时间:2019-07-15 04:06:20

标签: reactjs react-hooks

我正在提取带有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]);
}

3 个答案:

答案 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);
    });
  }, []);
}