更改状态变量的值时出现此延迟的原因是什么?

时间:2020-09-14 02:30:49

标签: reactjs

具有以下代码,我希望在更改价格和数量的值时,在父组件中修改产品的状态,这部分起作用,因为更新信息存在延迟,因此我必须将值写两倍价格和数量可以看到一些结果。更改状态变量的值时出现这种延迟的原因是什么?

import React, { useState } from "react";

const initialState = [
  {
    id: 1,
    name: "Nintendo switch",
    price: 250,
    quantity: 0,
    subTotal: 0
  },
  {
    id: 2,
    name: "Nintendo 3DS",
    price: 199,
    quantity: 0,
    subTotal: 0
  },
  {
    id: 3,
    name: "playstation 4",
    price: 300,
    quantity: 0,
    subTotal: 0
  }
];

function Totals({ products }) {
  function getTotal(key) {
    return products.reduce((previousValue, currentValue) => {
      return (previousValue += currentValue[key]);
    }, 0);
  }

  return (
    <tr>
      <td />
      <td>{getTotal("price")}</td>
      <td>{getTotal("quantity")}</td>
      <td>{getTotal("subTotal")}</td>
    </tr>
  );
}

function Product({ product, onChange }) {
  const [price, setPrice] = useState(product.price);
  const [quantity, setQuantity] = useState(product.quantity);

  function onChangePrice(event) {
    setPrice(event.target.value);

    onChange({ id: product.id, price, quantity });
  }

  function onChangeQuantity(event) {
    setQuantity(event.target.value);

    onChange({ id: product.id, price, quantity });
  }

  return (
    <tr>
      <td>{product.name}</td>
      <td>
        <input onChange={onChangePrice} value={price} />
      </td>
      <td>
        <input onChange={onChangeQuantity} value={quantity} />
      </td>
      <td>{product.subTotal}</td>
    </tr>
  );
}

function App() {
  const [products, setProducts] = useState(initialState);

  function onChangeHandler(entry) {
    const output = products.map(product =>
      product.id === entry.id
        ? {
            ...product,
            price: +entry.price,
            quantity: +entry.quantity,
            subTotal: +entry.price * +entry.quantity
          }
        : product
    );

    setProducts(output);
  }

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
          <th>Quantity</th>
          <th>Sub total</th>
        </tr>
      </thead>
      <tbody>
        {products.map(product => (
          <Product
            key={product.id}
            product={product}
            onChange={onChangeHandler}
          />
        ))}
        <Totals products={products} />
      </tbody>
    </table>
  );
}

export default App;

请看一下这个例子

https://codesandbox.io/s/gracious-ride-tixs1

2 个答案:

答案 0 :(得分:2)

问题在于,您实际上是将状态存储在2个地方,而它们并不总是一致的。 Product组件应该是无状态的,因为您要保持产品列表中的状态。

function Product({ product, onChange }) {

  function onChangePrice(e) {
    onChange({ id: product.id, price: e.target.value, quantity: product.quantity });
  }

  function onChangeQuantity(e) {
    onChange({ id: product.id, quantity: e.target.value, price: product.price });
  }

  return (
    <tr>
      <td>{product.name}</td>
      <td>
        <input onChange={onChangePrice} value={product.price} />
      </td>
      <td>
        <input onChange={onChangeQuantity} value={product.quantity} />
      </td>
      <td>{product.subTotal}</td>
    </tr>
  );
}

答案 1 :(得分:1)

尽管Product local pricequantity的设置正确,但是您正在呼叫onChange,这是道具由父组件向下传递,并带有 old 值:

function onChangePrice(event) {
  setPrice(event.target.value);

  onChange({ id: product.id, price, quantity });
}

function onChangeQuantity(event) {
  setQuantity(event.target.value);

  onChange({ id: product.id, price, quantity });
}

如果出于某种原因您确实需要在子组件和父组件中存储价格和数量,请确保使用onChange而不是 old来调用event.target.value pricequantity中的值:

function onChangePrice(event) {
  setPrice(event.target.value);

  onChange({ id: product.id, price: event.target.value, quantity });
}

function onChangeQuantity(event) {
  setQuantity(event.target.value);

  onChange({ id: product.id, price, quantity: event.target.value });
}