Как упоминалось в комментариях и ссылка предоставляется, 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
и установите для цепочки зависимостей значение []
, чтобы он запускался только один раз при первом рендеринге, а не каждый раз при обновлении состояния.
Ниже приведен пример, демонстрирующий получение / установку значений из localStorage, а также напрямую обновляет состояние.
CodeSandbox Demo
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>
);
}