react hooks 的 useState 如何获取最新的 state?

直接上代码吧,类似于之前class组件this.setState的第二个callback参数

import React, { useState, useEffect } from 'react';
import fetchData from 'services';

function useList() {
  const [params, setParams] = useState({});
  const [data, setData] = useState({});
  const getData = () => {
    fetchData(params).then(res => {
      setData(res);
    });
  };
  useEffect(() => {
    getData();
  }, []);
  return {
    params,
    setParams,
    data,
    setData,
    getData,
  };
}

function Foo() {
  const { setParams, getData } = useList();
  const handleClick = () => {
    setParams({ mockData: 2333333 });
    // 如何让getData里params是最新的???
    getData();
  };
  return (
    <button onClick={handleClick}>click me</button>
  );
}
阅读 21.9k
4 个回答

简单啊。

setParams({ mockData: 2333333 });
// 如何让getData里params是最新的???
getData();

改为:

setParams({ mockData: 2333333 });
setParams(currParams => {
    getData(currParams)
    return currParams
})

或者:

setParams(()=>{
    const nextParams = { mockData: 2333333 }
    getData(nextParams)
    return nextParams
});

其实这里使用 hook 的姿势不对啊,如果 getData 依赖于 params,同时期望每次 params 改变时,都调用 getData,那么 getData 应当使用 React.useEffect 封装并声明 paramsdeps

如果 getData 依赖于 params,但是期望每次 params 改变时,getData 的调用时机取决于调用者,那么这种情况下,setParams 的调用不应当暴露给调用者。为什么呢?因为依赖 params 状态的是 getData,它必然会获取到有效的、最新的 params,所以这种情况下,应当将 params 作为参数传递给 getData,并让其负责 params 状态的持久化工作。

如果 getData 依赖于 params,但又期望通过外部来设置 params,然后 getData 获取最新值,那需要借助 React.useRef 来保证 params 不被闭包锁定。


最后更新一波,可以看 dan 的这个文章,making-setinterval-declarative-with-react-hooks,关于 react 新的编程模型,基本说的很清楚了。

const getData = useCallback(() => {
    fetchData(params).then(res => {
      setData(res);
    });
}, [params, setData]);

const { setParams,data, getData } = useList();
当data更新时Foo会拿到最新的data的 不需要额外做处理

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题