Promise链式调用结合useState setState无法正常工作的问题
问题分析与解决方案
你的代码存在两个核心问题:
- setState异步特性导致状态未及时更新:调用
setDataDB后,React不会立刻更新dataDB状态,后续直接访问状态里的dataDB还是初始的null,导致tabs.find无法找到对应值。 - Promise链的参数传递错误:第一个
then没有返回任何值,所以第二个then的参数dataContent是undefined,你打印的是这个参数而非状态中的dataContent。
解决方案一:直接使用fetch返回的数据(推荐)
不需要依赖状态更新,在拿到接口返回的数据后直接计算role,同步设置两个状态:
const [dataDB, setDataDB] = useState(null); const [dataContent, setDataContent] = useState(null); ... useEffect(() => { fetch('some-url.com') .then((res) => res.json()) .then((fetchedData) => { setDataDB(fetchedData); console.log("dataDB: ", fetchedData); // 直接用接口返回的数据计算role,不用等状态更新 const role = tabs.find(x => x.id === fetchedData[0][0] + 1); setDataContent(role); console.log("dataContent: ", role); }) }, [tabs]) // 依赖中加入tabs,避免闭包引用旧值
解决方案二:监听dataDB状态变化更新dataContent
如果必须依赖dataDB状态更新后再处理,可以新增一个useEffect监听dataDB的变化:
const [dataDB, setDataDB] = useState(null); const [dataContent, setDataContent] = useState(null); ... // 负责请求数据 useEffect(() => { fetch('some-url.com') .then((res) => res.json()) .then((fetchedData) => { setDataDB(fetchedData); console.log("dataDB: ", fetchedData); }) }, []) // 监听dataDB变化,更新dataContent useEffect(() => { if (!dataDB) return; // 确保dataDB有值再处理 const role = tabs.find(x => x.id === dataDB[0][0] + 1); setDataContent(role); console.log("dataContent: ", role); }, [dataDB, tabs]) // 依赖dataDB和tabs
关键说明
- React的
setState是异步批量更新的,不要在调用setState后立刻访问对应的状态,否则拿到的是更新前的值。 - Promise链中,每个
then的参数是前一个then的返回值,如果前一个then没有return,则参数为undefined。
内容的提问来源于stack exchange,提问作者Lewis
相关产品推荐
相关产品推荐

