当我调用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,我不确定这是否会有所作为。我不能使用普通变量,因为它们会在每个渲染器上重置。
答案 0 :(得分:1)
setProductPage
将更新状态并触发新的渲染。 productPage
不是状态,它只是一个变量,用于保存您使用useState时的状态值。它永远不会改变,它将始终具有相同的值。您认为它会改变,但是实际上,该函数只是再次执行,但是现在productPage
分配了新值。
那你该怎么办?您有两种选择。
它使用useEffect的那个,它将查看productPage
是否发生更改(每次执行该函数=重新渲染),如果更改,它将获取数据并使用setDisplayProducts
进行更改。用displayProducts
中的新值重新渲染组件。如果您打算采用其他方式来更新productPage,并且希望它们也触发获取,则很好。
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
,但在获取而不是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));
};
答案 1 :(得分:1)
设置状态是异步操作,您不能像同步操作一样使用它。
因此,您必须使用 useEffect 挂钩,该挂钩在状态更改后运行。
import React, {useState, useEffect} from 'react';
const [productPage, setProductPage] = useState(1)
const [displayProducts, setDisplayProducts] = useState([])
const fetchProducts = async () => {
setProductPage(productPage + 1)
}
useEffect(() => {
const newProductsData = await fetch(`/api/getproducts?page=${productPage}`)
const newProductsArr = await newProductsData.json()
setDisplayProducts(displayProducts.concat(newProductsArr))
}, [productPage]); // <-- monitor productPage for changes