反应本机状态不变
react native state not changing
我想使用钩子将字符串从 asyncstorage
传递到状态变量,但它不起作用,尝试了几个小时但仍然不起作用。
这是代码:
const [cartitems, cartitemsfunc] = useState('');
const d = async () => {
let items = await AsyncStorage.getItem('items');
console.log('items from cart:' + items);
cartitemsfunc(items);
console.log('items from cart2:' + cartitems);
};
d();
当我尝试控制台日志记录时 cartitems
它在控制台中记录了一个空字符串,但是 items
记录了该字符串
谁能告诉我哪里错了
提前致谢!!!
由于 setState
是异步的,您需要观察它何时完成,这可以使用 useEffect
并将 caritems
添加到依赖项数组
中轻松完成
const [cartitems, cartitemsfunc] = useState('');
const d = async () => {
let items = await AsyncStorage.getItem('items');
console.log('items from cart:' + items);
cartitemsfunc(items);
};
useEffect(()=> {
console.log('items from cart2:' + cartitems);
}, [caritems]);
d();
我认为这里 console.log() 语句是在更新状态之前执行的。由于这里使用了 await,因此它将在获取结果之前执行下一行。
因此,在这种情况下,我们结合使用 useEffect() 和 useState()。 useEffect() 用于获取数据,useState() 用于更新状态并重新渲染 UI.
如评论中所述和提供的 ,useState
是异步的,因此设置一个值并立即在下一行中读取它不会产生一致的结果:
cartitemsfunc(items); // async call
console.log('items from cart2:' + cartitems); // cartitems not updated yet
同样重要的是要了解,每当您使用 useState
更新状态时,组件将再次呈现。如果您在应用程序主体中有方法调用,则每次更新状态时都会 运行 。因此,您所遇到的情况是您正在调用更新状态,但该方法正在执行并最终覆盖您的更改。
const d = async () => {
let items = await AsyncStorage.getItem('items');
console.log('items from cart:' + items);
cartitemsfunc(items);
console.log('items from cart2:' + cartitems);
};
d(); // this will run every time the component renders - after you update state
如果您只需要初始渲染时的值,则从 useEffect
调用方法并将依赖链设置为 []
,这样它在第一次渲染时只需要 运行s 一次,而不是每次更新状态时。
下面的示例演示了来自 localStorage 的 getting/setting 值并直接更新状态。
import React, { useState, useEffect } from "react";
import AsyncStorage from "@react-native-community/async-storage";
import "./styles.css";
export default function App() {
const [cartItems, setCartItems] = useState(null);
const setLSItems = async () => {
await AsyncStorage.setItem(
"items",
JSON.stringify([{ id: "foo", quantity: 1 }, { id: "bar", quantity: 2 }])
);
getLSItems(); // or setCartItems("Foo");
};
const clearLSItems = async () => {
await AsyncStorage.removeItem("items");
getLSItems(); // or or setCartItems(null);
};
const getLSItems = async () => {
const items = await AsyncStorage.getItem("items");
setCartItems(JSON.parse(items));
};
// bypass using local storage
const setCartItemsDirectly = () => {
setCartItems([{ id: "baz", quantity: 3 }]);
};
useEffect(() => {
getLSItems();
}, []); // run once at start
return (
<div className="App">
<div>
<button onClick={setLSItems}>Set LS Items</button>
<button onClick={clearLSItems}>Clear LS Items</button>
</div>
<div>
<button onClick={setCartItemsDirectly}>Set Cart Items Directly</button>
</div>
<hr />
{cartItems &&
cartItems.map((item, index) => (
<div key={index}>
item: {item.id} | quantity: {item.quantity}
</div>
))}
</div>
);
}
我想使用钩子将字符串从 asyncstorage
传递到状态变量,但它不起作用,尝试了几个小时但仍然不起作用。
这是代码:
const [cartitems, cartitemsfunc] = useState('');
const d = async () => {
let items = await AsyncStorage.getItem('items');
console.log('items from cart:' + items);
cartitemsfunc(items);
console.log('items from cart2:' + cartitems);
};
d();
当我尝试控制台日志记录时 cartitems
它在控制台中记录了一个空字符串,但是 items
记录了该字符串
谁能告诉我哪里错了
提前致谢!!!
由于 setState
是异步的,您需要观察它何时完成,这可以使用 useEffect
并将 caritems
添加到依赖项数组
const [cartitems, cartitemsfunc] = useState('');
const d = async () => {
let items = await AsyncStorage.getItem('items');
console.log('items from cart:' + items);
cartitemsfunc(items);
};
useEffect(()=> {
console.log('items from cart2:' + cartitems);
}, [caritems]);
d();
我认为这里 console.log() 语句是在更新状态之前执行的。由于这里使用了 await,因此它将在获取结果之前执行下一行。
因此,在这种情况下,我们结合使用 useEffect() 和 useState()。 useEffect() 用于获取数据,useState() 用于更新状态并重新渲染 UI.
如评论中所述和提供的 useState
是异步的,因此设置一个值并立即在下一行中读取它不会产生一致的结果:
cartitemsfunc(items); // async call
console.log('items from cart2:' + cartitems); // cartitems not updated yet
同样重要的是要了解,每当您使用 useState
更新状态时,组件将再次呈现。如果您在应用程序主体中有方法调用,则每次更新状态时都会 运行 。因此,您所遇到的情况是您正在调用更新状态,但该方法正在执行并最终覆盖您的更改。
const d = async () => {
let items = await AsyncStorage.getItem('items');
console.log('items from cart:' + items);
cartitemsfunc(items);
console.log('items from cart2:' + cartitems);
};
d(); // this will run every time the component renders - after you update state
如果您只需要初始渲染时的值,则从 useEffect
调用方法并将依赖链设置为 []
,这样它在第一次渲染时只需要 运行s 一次,而不是每次更新状态时。
下面的示例演示了来自 localStorage 的 getting/setting 值并直接更新状态。
import React, { useState, useEffect } from "react";
import AsyncStorage from "@react-native-community/async-storage";
import "./styles.css";
export default function App() {
const [cartItems, setCartItems] = useState(null);
const setLSItems = async () => {
await AsyncStorage.setItem(
"items",
JSON.stringify([{ id: "foo", quantity: 1 }, { id: "bar", quantity: 2 }])
);
getLSItems(); // or setCartItems("Foo");
};
const clearLSItems = async () => {
await AsyncStorage.removeItem("items");
getLSItems(); // or or setCartItems(null);
};
const getLSItems = async () => {
const items = await AsyncStorage.getItem("items");
setCartItems(JSON.parse(items));
};
// bypass using local storage
const setCartItemsDirectly = () => {
setCartItems([{ id: "baz", quantity: 3 }]);
};
useEffect(() => {
getLSItems();
}, []); // run once at start
return (
<div className="App">
<div>
<button onClick={setLSItems}>Set LS Items</button>
<button onClick={clearLSItems}>Clear LS Items</button>
</div>
<div>
<button onClick={setCartItemsDirectly}>Set Cart Items Directly</button>
</div>
<hr />
{cartItems &&
cartItems.map((item, index) => (
<div key={index}>
item: {item.id} | quantity: {item.quantity}
</div>
))}
</div>
);
}