React 18种新的状态更新方式要不要?

问题描述 投票:0回答:1

我在 React 中遇到了状态更新的特殊问题,这不是一个错误,我的代码工作正常,但我感觉有点奇怪。最初,我有一个产品状态,其中包含从 API 获取的所有产品:

const [products, setProducts] = useState<Product[]>([]);

我创建了一个更改产品信息的功能。尽管我没有更新之前产品的状态,但描述仍然更改为新产品:

const handleChangeProduct = async ({ productId }: Product) => {
  const exitsProduct = products.find(({ id }) => id === productId);
  exitsProduct.description = "example desc";
  const response = await fetch(
    `${process.env.VITE_APP_API_URL}/products/add`,
    {
      method: 'POST',
      body: JSON.stringify(exitsProduct),
    }
  );
  const responseObj = await response.json();
  // Update the products state, I don't know why the products state is update the description to `example desc`.
  if (responseObj?.success) {
    setProducts(products);
  }
} 

自从我开始使用 React 以来,这是我认为更新状态的正确方法。

const updatedProducts = products.map((product) => {
  if (product.id === productId) {
    return {
     ...product,
     description: product.description,
    }
  }
  return product;
});
setProducts(updatedProducts);

如果这是由于我对 ReactJS 缺乏了解,请告诉我。即使我们将状态复制到新常量,我们实际上可以更新新产品状态吗?

javascript reactjs
1个回答
0
投票

我想你知道所示的

handleChangeProduct
打破了React状态的基本规则:不要直接修改状态成员。我想您是在问,如果函数做错了,为什么您会看到更新的描述。

这是因为React可能会因为其他原因重新渲染你的组件,并且在重新渲染时,它会使用state中对象的当前属性,包括错误更新的属性。错误更新它们的问题在于,无法保证 React 何时或是否会呈现您所做的更改。为了正确确保 React 呈现更改,您需要执行

updatedProducts
函数的操作:创建一个新数组,并为要更新的产品创建一个新对象。


旁注:

setProducts(products);
中的
handleChangeProduct
调用不会执行任何操作,因为
products
(数组)没有更改(至少在显示的代码中没有更改),即使其中一个对象的属性数组中的内容已更改。

© www.soinside.com 2019 - 2024. All rights reserved.