Javascript 使用React钩子更新React中的状态
最近使用Javascript 使用React钩子更新React中的状态,javascript,reactjs,Javascript,Reactjs,最近使用useStatehook更新React应用程序内部的状态时遇到了困难 如果我将提供程序中的状态定义为- const [session, setSession] = useState({}); const [sessionId, setSessionId] = useState(0); 然后尝试使用setSession setSession(response.data); 它总是作为默认值返回。这一切都发生在提供者组件内部,即,我试图访问同一提供者中其他函数中的信息 但是,例如,如果我
useState
hook更新React应用程序内部的状态时遇到了困难
如果我将提供程序中的状态定义为-
const [session, setSession] = useState({});
const [sessionId, setSessionId] = useState(0);
然后尝试使用setSession
setSession(response.data);
它总是作为默认值返回。这一切都发生在提供者组件内部,即,我试图访问同一提供者中其他函数中的信息
但是,例如,如果我将该数据存储在localStorage中,那么访问它就不会有任何问题
localStorage.setItem("session", JSON.stringify(response.data));
我已经验证了来自服务器的信息是一个对象,并且数据是正确的。没有错误或承诺,只有包含响应的对象。如果我将代码片段setSession(response.data)
和localStorage.setItem(“session”,JSON.stringify(response.data))
放在一起,那么setSession
会将session
的值保留为{}
,而设置本地存储则效果很好。两者都使用相同的API响应、相同的数据
//这是我试图使用的组件上的方法来更新状态
const updateStateAfterSessionInitialization=异步数据=>{
设置会话(数据)
setItem(“session”,JSON.stringify(data));
setSessionId(data.id);
//尽管上面设置了值,但这两个日志都记录了值`{}`和` 0'
console.log(会话)
console.log(sessionId)
closeStartSessionModal();
//如果我像这样重定向我的应用程序,它可以正常工作。ID是服务器返回的正确值
window.location=“/#/reading sessions/”+data.id;
}
//下面的所有代码都封装在一个函数中。这些代码都不是在顶层执行的
让响应=等待axios({
方法:方法,,
数据:数据,
url:url,
标题:标题
});
等待更新会话初始化(response.data);
实际上,所有的数据都工作得非常好。服务器使用正确的数据进行响应,正确的数据存储在本地存储中的会话中。如果我使用来自服务器的对象的ID进行重定向,它可以正常工作。但是,如果我试图更新组件的状态并正确访问该状态,它就是不起作用,因此我必须尝试找到解决设置状态的方法
我有什么误解吗
我使用的代码在这里-
谢谢,例如:
import React, { useState, useEffect } from "react";
import axios from "axios";
function App() {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios("https://jsonplaceholder.typicode.com/posts");
console.log(result.data);
setData(result.data);
};
fetchData();
}, []);
return (
<ul>
{data.map(res => (
<li>{res.title}</li>
))}
</ul>
);
}
export default App;
import React,{useState,useffect}来自“React”;
从“axios”导入axios;
函数App(){
const[data,setData]=useState([]);
useffect(()=>{
const fetchData=async()=>{
常量结果=等待轴(“https://jsonplaceholder.typicode.com/posts");
console.log(result.data);
setData(result.data);
};
fetchData();
}, []);
返回(
{data.map(res=>(
- {res.title}
))}
);
}
导出默认应用程序;
检查您的响应类型。数据并定义类型
数组-[]
对象-{}
字符串-“”
useState中的数字-0
您在这里的误解是假设状态更新将立即反映,这是不正确的
状态更新是异步的,仅在下一个渲染周期中引用。如果您尝试更新状态并将其记录在下一行中,您将无法看到和更新状态
// This is the method on my component that I'm trying to use to update the state
const updateStateAfterSessionInitialization = async data => {
setSession(data)
localStorage.setItem("session", JSON.stringify(data));
setSessionId(data.id);
// both of these log a value of `{}` and `0` despite the values being set above
console.log(session) // This is expected to log previous value
console.log(sessionId) // This is expected to log previous value
closeStartSessionModal();
window.location = "/#/reading-sessions/" + data.id;
}
现在localStorage是同步的,因此它的更新会立即反映出来
如果希望查看状态更新是否正确完成,可以编写一个依赖于状态更新的useEffect
useEffect(() => {
console.log('State session/sessionId updated');
}, [session, sessionId])
现在,根据您试图实现的目标,您需要根据上面的语句修改代码,即状态更新调用是异步的
此外,setSession不会返回承诺,因此不能仅使用async Wait。您需要使用useffect
对状态更新采取操作设置状态为异步,因此新值将应用于下一个重新渲染器,而不是下一行。您的响应是什么。数据
?你从哪里得到的?你能分享一下setSession(response.data)的周边代码吗代码>?响应。数据
未定义。似乎您正在使用axios发出一些API请求。可能您没有使用async/await,即.then()
发出请求时,URL可能错误(输入错误)或API服务器已关闭。正如您所看到的,如果您添加一个更完整的代码段,您可以缩小它的范围。谢谢,我认为我们从发布的代码中看不到全部情况。更多的代码或代码沙盒是值得赞赏的。我已经验证了它是一个对象。我已经查看了服务器和本地存储的响应啊,好的。我想我误解的是,react会在状态改变时重新呈现。这是设置状态的情况,否?这个提供者最初是基于类的,因此使用了这种方法,我没有任何问题。我只是更新了它,因为我的所有其他提供者都是基于函数的。如果我恢复到基于类的提供程序并使用setState
,可能会更好。这个解释非常有用。非常感谢你!实际上,类和功能组件之间在行为上并没有太大的差异。循环仍然是一样的。一些API已经改变。状态更新时为“是”,会触发重新渲染,但不会更改函数范围值