防止状态覆盖 React

huangapple go评论72阅读模式
英文:

Prevent State Overwrite React

问题

以下是您要翻译的内容:

I have a case like this
I have a current product

0: {id: "abc", name: "bigu", qty: 1, remarks: "nice"},
1: {id: "def", name: "moo", qty: 1, remarks: "handsome"}

When I add a new product

0: {id: "abc", name: "bigu", qty: 1, remarks: ""},
1: {id: "def", name: "moo", qty: 1, remarks: ""},
2: {id: "ghi", name: "ucing", qty: 1, remarks: ""},
3: {id: "jkl", name: "kepi", qty: 1, remarks: ""}

this is my first state and useEffect that change product list everytime I called addReq.product

const [productsLists, setProductsLists] = useState<Product[]>(addReq.product)

useEffect(() => {
    setProductsLists(addReq.product)
  }, [addReq.product])

I want the setProductsLists is not overwrite the current product that I already have and just adding a new product to the current array. The addReq is from my redux.

I already tried this methods but it causing infinite loops.

useEffect(() => {
  setProductsLists(prevProducts => {
    // Create a new array with the existing products and new products
    const updatedProducts = [...prevProducts, ...addReq.product];

    // Update the remarks of only the new products to an empty string
    const updatedProductsLists = updatedProducts.map((product, index) => {
      if (index >= prevProducts.length) {
        return { ...product, remarks: "" };
      }
      return product;
    });

    return updatedProductsLists;
  });
}, [addReq.product]);
英文:

I have a case like this
I have a current product

0: {id: "abc", name: "bigu", qty: 1, remarks: "nice"},
1: {id: "def", name: "moo", qty: 1, remarks: "handsome"}

When I add a new product

0: {id: "abc", name: "bigu", qty: 1, remarks: ""},
1: {id: "def", name: "moo", qty: 1, remarks: ""},
2: {id: "ghi", name: "ucing", qty: 1, remarks: ""},
3: {id: "jkl", name: "kepi", qty: 1, remarks: ""}

this is my first state and useEffect that change product list everytime I called addReq.product

const [productsLists, setProductsLists] = useState<Product[]>(addReq.product)

useEffect(() => {
    setProductsLists(addReq.product)
  }, [addReq.product])

I want the setProductsLists is not overwrite the current product that I already have and just adding a new product to the current array. The addReq is from my redux.

I already tried this methods but it causing infinite loops.

useEffect(() => {
  setProductsLists(prevProducts => {
    // Create a new array with the existing products and new products
    const updatedProducts = [...prevProducts, ...addReq.product];

    // Update the remarks of only the new products to an empty string
    const updatedProductsLists = updatedProducts.map((product, index) => {
      if (index >= prevProducts.length) {
        return { ...product, remarks: "" };
      }
      return product;
    });

    return updatedProductsLists;
  });
}, [addReq.product]);

答案1

得分: 1

不要修改产品属性的备注,否则会修改数组中所有可用的产品的备注属性。

首先,执行一个操作,更新所需对象,然后将其添加到数组中。

useEffect(() => {
  let updateProdect = { ...addReq.product, remarks: "" };
  setProductsLists(prevProducts => {
    // 创建一个包含现有产品和新产品的新数组
    const updatedProducts = [...prevProducts, ...updateProdect];

    // 仅将新产品的备注更新为空字符串
    const updatedProductsLists = updatedProducts.map((product, index) => {
      if (index >= prevProducts.length) {
        return { ...product };
      }
      return product;
    });

    return updatedProductsLists;
  });
}, [addReq.product]);
英文:

>do not modified products properties remarks at the end it will modified all avaliable products in the array with remarks properties

>do one thing update the require object first and then add it to array

useEffect(() => {
let updateProdect = {...addReq.product,remarks: "" }
  setProductsLists(prevProducts => {
    // Create a new array with the existing products and new products
    const updatedProducts = [...prevProducts, ...updateProdect];

    // Update the remarks of only the new products to an empty string
    const updatedProductsLists = updatedProducts.map((product, index) => {
      if (index >= prevProducts.length) {
        return { ...product};
      }
      return product;
    });

    return updatedProductsLists;
  });
}, [addReq.product]);

答案2

得分: -2

你可以使用UseRef:

const productsList = useRef<Product[]>();
useEffect(() => {
    productsList.current = { ...productsList.current, addReq.product };
}, [addReq.product]);

但是,你应该明白改变productsList.current并不会重新渲染组件:不会发生进一步的更改(你无法渲染新修改的 "productsList")。

你最好考虑使用useSelector和useDispatch(与reducers一起使用):

const products = useSelector(state => state.products);
const dispatch = useDispatch();
const setProducts = (newProducts: Product[]) => {
    dispatch(setProducts([...products, ...newProducts]));
}

调用setProducts将导致一个"修改过的"产品列表。

英文:

you can use UseRef:

const productsList = useRef&lt;Product[]&gt;();
useEffect(() =&gt; {
    productsList.ref = { ...productsList, addReq.product };
}, [addReq.product]);

But, you should understand that changing productsList.ref does not re-render the component: no further changes occur(you cannot render newly modified "productsList").

you'd better consider using useSelector and useDispatch(with reducers).

const products = useSelector(state =&gt; state.products);
const dispatch = useDispatch();
const setProducts = (newProducts: Product[]) =&gt; {
    dispatch(setProducts([...products, ...newProducts]));
}

calling setProducts will lead to a "modified" productList

huangapple
  • 本文由 发表于 2023年5月29日 13:13:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定