React Native中AsyncStorage值无法通过useState获取问题求助
问题原因与解决办法
核心问题
React里useState的更新是异步批量执行的,你调用setUsername(value1)后,username并不会立刻变成value1。所以在useEffect里刚调用完getData()就打印username、password,或者直接用它们发请求,拿到的还是初始的undefined。
另外你当前的useEffect把username、password设为依赖,会导致无限循环:初始执行→调用getData更新state→依赖变化触发useEffect再次执行→又调用getData→再次更新state……
两种解决思路
思路1:直接用AsyncStorage取出的值发请求(最简洁)
既然已经能从AsyncStorage拿到正确的值,没必要绕一圈存state再用,直接在getData里拿到值后就发起请求:
function Home(props) { const [username, setUsername] = useState(); const [password, setPassword] = useState(); const getData = async () => { try { const value1 = await AsyncStorage.getItem("login"); const value2 = await AsyncStorage.getItem("password"); setUsername(value1); setPassword(value2); console.log("retrieved value from async storage ", value1, value2); // 直接用拿到的值发请求 axios .post("https://........", { auth: { username: value1, password: value2, }, }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); } catch (e) { // 处理读取错误 console.error("读取AsyncStorage失败", e); } }; useEffect(() => { getData(); // 这里不用加username、password作为依赖,避免循环 }, []); }
思路2:用state存值,监听state变化发请求
如果确实需要把用户名密码存在state里,就拆分两个useEffect:一个负责初始化获取数据,另一个监听state变化,只有当state有值时才发请求:
function Home(props) { const [username, setUsername] = useState(); const [password, setPassword] = useState(); const getData = async () => { try { const value1 = await AsyncStorage.getItem("login"); const value2 = await AsyncStorage.getItem("password"); setUsername(value1); setPassword(value2); console.log("retrieved value from async storage ", value1, value2); } catch (e) { console.error("读取AsyncStorage失败", e); } }; // 第一个useEffect:组件挂载时获取数据 useEffect(() => { getData(); }, []); // 第二个useEffect:监听state变化,有值时发请求 useEffect(() => { // 先判断值是否存在,避免初始undefined时发无效请求 if (!username || !password) return; console.log("stored value ", username, password); axios .post("https://........", { auth: { username: username, password: password, }, }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); }, [username, password]); }
关键注意点
- 永远记住
useState更新是异步的,不要期望调用setter后立刻拿到新值。 - 给
useEffect加依赖时要小心,避免不必要的重复执行甚至无限循环。
内容的提问来源于stack exchange,提问作者tomtom
相关产品推荐
相关产品推荐

