React中使用async/await+axios时state输出undefined的问题
问题:React调用setData后立即打印data显示undefined的原因
我正在开发一款从Openweathermap API获取数据并展示的基础天气应用。遇到一个疑惑:下面的代码中,调用setData(res.data)后立刻执行console.log(data),控制台显示的是undefined,但实际上数据已经成功获取,而且通过data &&判断渲染页面的逻辑也能正常显示内容。
请求数据的代码片段:
const [data, setData] = useState() useEffect(() => { const fetchData = async () => { const res = await axios.get(url) setData(res.data) console.log(data) // 这里打印undefined } fetchData() }, [])
页面渲染代码:
return ( {data && ( <div className="weather"> // 内容写在这里 </div> )} )
我原本以为console.log(data)会在await执行完成后才运行,实在搞不懂为什么会显示undefined,恳请解答。
解答
这是因为React的state更新是异步且批量处理的,再加上JavaScript的闭包特性,导致你在当前函数里捕获到的data是更新前的旧值。
具体拆解:
- 组件第一次渲染时,
data的初始值是undefined,此时useEffect里的fetchData函数被创建,它捕获了这个初始的data变量。 - 当
await axios.get(url)完成后,调用setData(res.data)只是给React发了一个“要更新state”的通知,但React不会立刻修改data的值,而是会安排一次组件重新渲染。 - 所以你紧接着执行的
console.log(data),打印的还是fetchData函数创建时捕获的那个初始undefined——当前函数还没执行完,新的data值要等到组件重新渲染后才会生成。
至于页面能正常渲染,是因为React处理完state更新后会重新渲染组件,此时data已经是API返回的新值,data &&的判断条件成立,内容自然就能显示出来。
如果想要看到更新后的data,可以用这两种方法:
- 方法一:在组件渲染阶段打印(比如return语句前后)
- 方法二:新增一个监听
data变化的useEffect:useEffect(() => { console.log(data) // 当data更新时会打印新值 }, [data])
内容的提问来源于stack exchange,提问作者newportkat
相关产品推荐
相关产品推荐

