首页 > 解决方案 > applying map function works while foreach function doesnt reactjs

问题描述

I have a react app which show items from a nested json using map function, however one of the categories can be empty which crashes the whole application, I have tested the foreach function for the same json using js's for each function and it worked perfectly, I am trying to translate the same logic which would solve the empty category issue.

here is my for each test on the same json but with lists:

Test1

let obj = {
  "name": "Menu",
  "children": [
    {
      "type": "category",
      "name": "Burgers",
      "children": [
        {
          "type": "item",
          "name": "Burger 1",
          "children": [
            {
              "type": "modifier",
              "name": "Promo",
              "children": [
                {
                  "type": "item",
                  "name": "Promo 1"
                }
              ]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [
                {
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [
                {
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Tomato"
                },
                {
                  "type": "ingredient",
                  "name": "Pickles"
                }
              ]
            }
          ]
        },
        {
          "type": "item",
          "name": "Burger 2",
          "children": [
            {
              "type": "modifier",
              "name": "Promo",
              "children": [
                {
                  "type": "item",
                  "name": "Promo 1"
                }
              ]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [
                {
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [
                {
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Tomato"
                },
                {
                  "type": "ingredient",
                  "name": "Pickles"
                }
              ]
            }
          ]
        },
        {
          "type": "item",
          "name": "Coming Soon Offers"
        }
      ]
    },
    {
      "type": "category",
      "name": "Pizzas",
      "children": [
        {
          "type": "item",
          "name": "Pizza 1",
          "children": [
            {
              "type": "modifier",
              "name": "Promo",
              "children": [
                {
                  "type": "item",
                  "name": "Promo 1"
                }
              ]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [
                {
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [
                {
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Mashrooms"
                },
                {
                  "type": "ingredient",
                  "name": "Olives"
                }
              ]
            }
          ]
        },
        {
          "type": "item",
          "name": "Pizza 2",
          "children": [
            {
              "type": "modifier",
              "name": "Promo",
              "children": [
                {
                  "type": "item",
                  "name": "Promo 1"
                }
              ]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [
                {
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [
                {
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Mashrooms"
                },
                {
                  "type": "ingredient",
                  "name": "Olives"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
let body = document.querySelector('body');
function print(obj){
  let str = `<li>${obj.name}</li>`;
  if(obj.children){
    str += '<ul>' 
    for(let c of obj.children) str += print(c)
    str += '</ul>'
  }
  return str;
}
document.body.innerHTML = print(obj);

Test 2

const buildMenu = (data) => {
  let ul = document.createElement('ul');
  data.children.forEach(i => {
    let li = document.createElement('li');
    li.innerText = i.name;
    li.className = i.type;
    if (i.children) li.appendChild(buildMenu(i));
    ul.appendChild(li);
  });

  return ul;
};

let data = {

  "name": "Menu",
  "children": [{
      "type": "category",
      "name": "Burgers",
      "children": [{
          "type": "item",
          "name": "Burger 1",
          "children": [{
              "type": "modifier",
              "name": "Promo",
              "children": [{
                "type": "item",
                "name": "Promo 1"
              }]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [{
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [{
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Tomato"
                },
                {
                  "type": "ingredient",
                  "name": "Pickles"
                }
              ]
            }
          ]
        },
        {
          "type": "item",
          "name": "Burger 2",
          "children": [{
              "type": "modifier",
              "name": "Promo",
              "children": [{
                "type": "item",
                "name": "Promo 1"
              }]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [{
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [{
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Tomato"
                },
                {
                  "type": "ingredient",
                  "name": "Pickles"
                }
              ]
            }
          ]
        },
        {
          "type": "item",
          "name": "Coming Soon Offers"
        }
      ]
    },
    {
      "type": "category",
      "name": "Pizzas",
      "children": [{
          "type": "item",
          "name": "Pizza 1",
          "children": [{
              "type": "modifier",
              "name": "Promo",
              "children": [{
                "type": "item",
                "name": "Promo 1"
              }]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [{
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [{
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Mashrooms"
                },
                {
                  "type": "ingredient",
                  "name": "Olives"
                }
              ]
            }
          ]
        },
        {
          "type": "item",
          "name": "Pizza 2",
          "children": [{
              "type": "modifier",
              "name": "Promo",
              "children": [{
                "type": "item",
                "name": "Promo 1"
              }]
            },
            {
              "type": "group",
              "name": "Drinks",
              "children": [{
                  "type": "item",
                  "name": "Coke"
                },
                {
                  "type": "item",
                  "name": "Light Coke"
                },
                {
                  "type": "item",
                  "name": "Sprite"
                },
                {
                  "type": "item",
                  "name": "Fanta"
                }
              ]
            },
            {
              "type": "modifier",
              "name": "Without",
              "children": [{
                  "type": "ingredient",
                  "name": "Onion"
                },
                {
                  "type": "ingredient",
                  "name": "Mashrooms"
                },
                {
                  "type": "ingredient",
                  "name": "Olives"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
};

document.body.appendChild(buildMenu(data));

标签: javascriptjsonreactjsecmascript-6foreach

解决方案


您在多个地方缺少对象空检查。

  1. ItemList组件的渲染函数中有一个 else 语句,您可以在其中分配 selectedChild 和 selectedItem。您需要检查activelist.childrenand selectedChild.children是否为空
   const selectedChild = activelist.children.length ? activelist.children[this.state.selected] : null;
   const selectedItem = selectedChild.children && selectedChild.children.length
        ? selectedChild.children[this.state.itemSelected]: null;
  1. 要渲染 selectedChild,您应该检查 children 是否为空。
{
  selectedChild &&
  selectedChild.children &&
  selectedChild.children.length &&
  selectedChild.children.map(
    (item, index) => (
      <Item
        className="person"
        key={index}
        Title={item.name}
        onClick={this.handleClick}
        index={index}
      />
   )
)}
  1. 要呈现 selectedItem,您应该检查 children 是否为空
<div>
  { selectedItem &&
    selectedItem.children &&
    selectedItem.children.map((item, index) => (
      <Modifiers
        key={index}
        title={item.name}
        myKey={index}
        options={item.children}
        childk={item.id}
       />
     ))
  }
</div>
<div>
  { 
    selectedItem &&
    selectedItem.size &&
    (<div>
        <Size
           options={selectedItem.size}
           sizetitle={"Size"}
        />
       </div>)
   }
</div>

推荐阅读