首页 > 解决方案 > 如何立即更新 react useState?

问题描述

当我打电话时,fetchProducts我希望在运行下一行代码之前更新 productPage 状态,因为下一行需要更新的状态。

状态仅在函数完成运行后更新。无论fetchProducts我把console.log(productPage)它放在函数的哪个位置,它都会返回调用函数之前的状态。

   const [productPage, setProductPage] = useState(1)
   const [displayProducts, setDisplayProducts] = useState([])

   const fetchProducts = async () => {

      setProductPage(productPage + 1) // DOES NOT UPDATE UNTIL AFTER FUNCTION RUNS

      const newProductsData = await fetch(`/api/getproducts?page=${productPage}`)
      const newProductsArr = await newProductsData.json()
      setDisplayProducts(displayProducts.concat(newProductsArr))

   }

这可能吗?我找到了解决该问题的方法,但感觉很笨拙且不理想。

我也在使用 next.js,我不确定这是否会有所作为。我不能使用普通变量,因为它们在每次渲染时都会重置。

标签: reactjsreact-hooksnext.js

解决方案


setProductPage将更新状态并触发新的渲染。productPage不是状态,它只是一个变量,保存您使用 useState 时的状态值。它永远不会改变,它将始终具有相同的价值。您认为它发生了变化,但实际上,该函数只是再次执行,但现在productPage分配了新值。

所以,你可以做什么?你有两个选择。

它使用 useEffect 的那个,它将查看是否productPage发生变化(每次执行函数时 = 重新渲染),如果是,它将获取数据并使用setDisplayProducts新值重新渲染组件displayProducts。如果您计划使用其他方式更新 productPage 并且您希望它们也触发 fetch,这很好。

const [productPage, setProductPage] = useState(1)
const [displayProducts, setDisplayProducts] = useState([])

const fetchProducts = async () => {
   setProductPage(productPage + 1);
}

useEffect(() => {
    const getDisplayProducts = async () => {
        const newProductsData = await fetch(`/api/getproducts?page=${productPage}`)
        const newProductsArr = await newProductsData.json()
        setDisplayProducts(displayProducts.concat(newProductsArr))
    };

    getDisplayProducts();
}, [productPage]);

第二个只是将新值存储在变量中,将变量传递给setProductPage但在 fetch 中使用变量而不是productPage

const [productPage, setProductPage] = useState(1)
const [displayProducts, setDisplayProducts] = useState([])

const fetchProducts = async () => {
    const nextProductPage = productPage + 1;

    setProductPage(nextProductPage);
    const newProductsData = await fetch(`/api/getproducts?page=${nextProductPage}`)
    const newProductsArr = await newProductsData.json()
    setDisplayProducts(displayProducts.concat(newProductsArr));
};

推荐阅读