我是React的初学者。我有2种不同的情况,我在使用React Hooks,但我无法正确地从本地API接收数据。
案例1:
export const RegisterT = () => {
const [test, setTest] = useState()
const addrState = {}
axios.get('http://127.0.0.1:3333/states', { addrState })
.then(res => {
setTest(res.data)
console.log(test)
})
...
}
它与状态test
一起正常显示API的内容,但我不知道Axios为什么/如何继续调用API无限-无止境。 (注:第一次调用返回未定义,然后下一个调用正常)我在做什么错?
为了解决这个问题,我尝试使用这种useEffect
(案例2):
export const RegisterT = () => {
const [test, setTest] = useState()
const addrState = {}
useEffect(() => {
axios.get('http://127.0.0.1:3333/states', { addrState })
.then(res => {
setTest(res.data)
console.log(test);
})
}, [])
...
}
现在,Axios仅能运行一次,但API不会发送任何数据。也许我应该在这种情况下使用异步/等待,但是我无法使其工作。有谁知道如何解决此问题(案例1或案例2)?
谢谢。
更新状态是异步操作。因此,state
直到下一次渲染该组件时才真正更新。如果要捕获正确的状态,可以将console.log(res.data)
或以useEffect
作为依赖项将其包装在test
挂钩中。
export const RegisterT = () => {
const [test, setTest] = useState()
const addrState = {}
// effect only runs when component is mounted
useEffect(() => {
axios.get('http://127.0.0.1:3333/states', { addrState })
.then(res => {
setTest(res.data);
});
}, []);
// effect runs whenever value of test changes
useEffect(() => {
console.log(test);
}, [test]);
}
这样可以确保console.log
的值在更新test
时运行。
也是API请求被调用一次的原因是您在依赖项数组中未提及任何内容。首次安装组件时,[]
空依赖项数组会运行该效果。
async/await
只是Promise
对象的包装。因此它们的行为类似。
useEffect
的解决方案很好。如果您不使用它,则每个渲染器都会调用该请求。如果您在console.log
中输入任何信息,也是如此。之所以看不到useEffect
中的数据,是因为状态值不会在当前渲染中更新,而是在下一个由状态设置器调用的状态中更新。将console.log(test);
移到useEffect
之后即可查看数据。初始化时它将为undefined
,但在下一个渲染中,它应包含来自请求的数据。