簡體   English   中英

反應原生 state 沒有改變

[英]react native state not changing

我想使用鈎子將字符串從asyncstorage傳遞給 state 變量,但它不起作用,嘗試了幾個小時但仍然不起作用。 這是代碼:

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();

正如提供的評論和鏈接中提到的, useState是異步的,因此設置一個值並立即在以下行中讀取它不會產生一致的結果:

cartitemsfunc(items); // async call
console.log('items from cart2:' + cartitems); // cartitems not updated yet

同樣重要的是要了解,每當您使用useState更新 state 時,組件都會再次呈現。 如果您在應用程序主體中有一個方法調用,它將在您每次更新 state 時運行。 因此,您所擁有的是一個場景,您正在調用更新 state,但該方法正在執行並最終覆蓋您的更改。

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調用該方法並將依賴鏈設置為[]以便它僅在第一次渲染時運行一次,而不是每次更新 state 時運行。

下面的示例演示了從 localStorage 獲取/設置值以及直接更新 state。

CodeSandbox 演示

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>
  );
}

我認為在更新 state 之前執行 console.log() 語句。 因為這里已經使用了 await,所以它會在得到結果之前執行下一行。

因此,在這種情況下,我們使用 useEffect() 和 useState() 的組合。 useEffect() 用於獲取數據,useState() 用於更新 state 並重新渲染 UI。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM