【问题标题】:Rendering an array of components with seperate states in React在 React 中渲染具有不同状态的组件数组
【发布时间】:2021-06-02 22:21:15
【问题描述】:

好的!因此,已经提出了与此类似的问题,但问题是它们不能解决我的确切问题,因此请阅读完整的问题并考虑查看下面粘贴的代码 sn-p,然后再将其标记为重复。所以我有一个对象数组menuItems,其中包含另一个组件MenuItem 的道具,我试图通过迭代该数组“menuItems”并分配独特的道具来多次渲染该组件MenuItem然后将其推送到另一个名为 items 的数组,完成后我将这个 items 数组放在返回中,但不知何故反应根本不会呈现该数组。

function Menu() {

    let items = [];

    const menuItems = [
        {
            imageName:'food-header-2.jpg',
            itemTitle:'Full breakfast for morning',
            itemPunchLine:'Some punchline',
            quantity:0,
        },
        {
            imageName:'pizza.jpg',
            itemTitle:'Cheeze pizza',
            itemPunchLine:'Some punchline',
            quantity:0,
        },
        {
            imageName:'burger.jpg',
            itemTitle:'Jumbo Burger',
            itemPunchLine:"Some punchline",
            quantity:0,
        },
        {
            imageName:'sandwich.jpg',
            itemTitle:'Veg SandWich',
            itemPunchLine:'Some punchline',
            quantity:0,
        },
        {
            imageName:'chocolate-shake.jpg',
            itemTitle:'Chocolate Shake',
            itemPunchLine:'Some punchline',
            quantity:0,
        },
    ]

    const useEffect(() => {

        menuItems.forEach((menuItem,index) => {
            items.push(
            <MenuItem key={index} title={menuItem.itemTitle} punchLine={menuItem.itemPunchLine} 
            quantity={menuItem.quantity} imageName={menuItem.imageName}
            />);
        }));

        
    };
    return(
        <div className="container">
            <div className="menu-holder">
                <div className="menu">
                    {items}                 
                </div>
            </div>            
        </div>
    )
}

【问题讨论】:

    标签: javascript arrays reactjs jsx


    【解决方案1】:

    items 是一个普通数组。它不是一个有状态的值(即使用 useState 钩子)。当这个值改变时,React 不会重新渲染。

    您应该在返回语句中直接使用map 呈现menuItems

     return(
        <div className="container">
            <div className="menu-holder">
                <div className="menu">
                    {menuItems.map((menuItem,index) => 
                      <MenuItem
                        key={index} 
                        title={menuItem.itemTitle} 
                        punchLine={menuItem.itemPunchLine} 
                        quantity={menuItem.quantity}
                        imageName={menuItem.imageName}
                      />)}
                </div>
            </div>
        </div>
    )
    

    ...

    如果您出于某种原因想要保留 items 数组,要遵循这种方法,您需要将其转换为反应状态。

    你可以这样实现它:

    import React, { useEffect, useState } from "react";
    
    const menuItems = [
      {
          imageName:'food-header-2.jpg',
          itemTitle:'Full breakfast for morning',
          itemPunchLine:'Some punchline',
          quantity:0,
      }
    ]
    
    function Menu() {
      const [items, setItems] = useState([]);
    
      useEffect(() => {
        setItems(menuItems)
      }, [])
    
      return(
          <div className="container">
              <div className="menu-holder">
                  <div className="menu">
                    {items.map((menuItem,index) => 
                      <MenuItem
                        key={index} 
                        title={menuItem.itemTitle} 
                        punchLine={menuItem.itemPunchLine} 
                        quantity={menuItem.quantity}
                        imageName={menuItem.imageName}
                      />)}
                  </div>
              </div>
          </div>
      )
    }
    

    但是,如果您在渲染时知道 menuItems,那么直接将初始状态设置为此会更有效(而不是在渲染后在 useEffect 挂钩中设置它:

      const [items, setItems] = useState(menuItems);
    

    【讨论】:

    • 这工作得非常好,但后来我尝试在useEffect 钩子中使用相同的array.map,然后尝试渲染它停止工作的数组并做出反应会引发错误Objects are not valid as React Child 我想问为什么会这样? map 如何使数组有状态?
    • 我已经扩展了答案,以尝试显示您应该使用的模式。 map 在 React 中没有使值有状态,它只是一种迭代数组并返回新数组的方法。
    【解决方案2】:

    为了让 React 观察状态变化,您可以使用 useState 挂钩来跟踪数组状态的变化。

    const [items, setItems] = useState([])
    

    【讨论】:

    • 你的意思是我应该在menuItems.forEach 循环内执行setItems([...items, newItem]) 吗?
    猜你喜欢
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    相关资源
    最近更新 更多