【问题标题】:Set State in a loop React Native在循环中设置状态 React Native
【发布时间】:2020-11-18 00:45:54
【问题描述】:

我有一些对象数组形式的道具,用于更新我的“项目”状态。我能够遍历对象并构建包含“product_id”和“数量”的对象。当我只是 console.log 时,我可以看到正确的数据,但是当我尝试更新状态时,我收到错误 "Too many re-renders, react limits the number of renders to prevent an infinite-loop."

 const [items, setItems] = useState(
    {
      product_id: 93,
      quantity: 2,
    },
    {
      product_id: 22,
      variation_id: 23,
      quantity: 1,
    },
  );
  const cart = props.cart;
  Object.keys(cart).forEach(function (key) {
    const prod = {
      product_id: cart[key].id,
      quantity: cart[key].quantity,
    };
    setItems((currentItems) => {
      return {prod, ...currentItems};
    });
  });

编辑 我的购物车道具是使用以下代码从 redux 中提取的

function mapStateToProps(state) {
  return {
    cart: state.cart,
  };
}
export default connect(mapStateToProps)(Checkout);

问题是这个道具有更多的属性,而不仅仅是我需要的数量和id。

【问题讨论】:

  • 作为购物车道具传入的值是什么?
  • 当您执行 setState 时,您的组件将伪装,这将导致重新触发您的 forEach 循环,该循环将触发重新渲染等等。您可以将 forEach 包装在 useEffect 中(它具有回调和依赖项作为参数)。如果你传递一个空数组作为依赖,它只会发生一次。
  • 为什么要设置状态而不只是使用道具值进行渲染?
  • cart 属性使用了 redux 属性和 MapStateToProp 函数。我不能只将它呈现给状态,因为它有我不需要的额外数据。我只需要从中提取 id 和数量。
  • 你不能在组件的全局级别调用setItems()。将状态更新代码封装在函数中,然后根据事件调用该函数(例如onClickonChange 或类似的东西)。此外,更新forEach 内部的状态也不是一个好主意。只需遍历数组并最终更新状态。

标签: javascript reactjs react-native react-state


【解决方案1】:

您无需在循环中一次又一次地设置状态。相反,只需在数组上循环,获取项目并最终设置状态

   const [items, setItems] = React.useState(
    {
      product_id: 93,
      quantity: 2
    },
    {
      product_id: 22,
      variation_id: 23,
      quantity: 1
    }
  );

  const { cart } = props;
  useEffect(() => {
    const products = Object.entries(cart).map(([key, { id, quantity }]) => ({
      product_id: id,
      quantity: quantity
    }));
    setItems(currentItems => ({ ...products, ...currentItems }));
  }, [cart]);

【讨论】:

    【解决方案2】:

    您应该使用数组或对象作为状态。您将两个单独的对象传递给 useState,用适当的键将它们包装在一个对象中。或使用数组。

    it seems you have forgotten to add a wrap your initial object inside curly braces.  
    
    const [items, setItems] = useState([
      {
        product_id: 93,
        quantity: 2,
      },
      {
        product_id: 22,
        variation_id: 23,
        quantity: 1,
      },
    ]);  
    

    然后

    return [prod, ...currentItems];  
    

    作为建议:
    最好是创建新对象并一次性将它们设置为状态。

    const objectsToAdd = Object.values(cart).map(function (cartItem) {
      return {
        product_id: cartItem.id,
        quantity: cartItem.quantity,
      };
    });
    
    setItems((currentItems) => {
      return [...objectsToAdd, ...currentItems];
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      • 2019-07-26
      • 2017-10-22
      • 1970-01-01
      相关资源
      最近更新 更多