基于深度嵌套数组的项目有条件地渲染组件

时间:2020-02-19 20:52:18

标签: javascript reactjs typescript

我有一个React组件,该组件正在接收从API响应返回的数据对象。

我正在尝试编写一个函数,该函数从该数据响应中接受一个字段,检查该字段中的元素,然后对其进行迭代,检查数组中的每个对象是否具有特定警报的值。

如果找到了特定警报的值,则需要为该警报呈现一个图标。

数据对象如下:

location: {
  ...,
details: {
  summary: [
            {
             type: 'calling',
             icon: 'phone' 
             },
             {
             type: 'power',
             icon: 'electric' 
             },
             {
             type: 'water',
             icon: 'water-icon' 
             },
           ]
        }
      }               

这是我要有条件地渲染图标的部分(这是我的初次尝试和初步尝试):

           <div>
            {location.alertDetails && (
                <IconBox title={`Alerts`}>
                  <IconSection>
                  {location.details.summary.includes(type === calling) && 
                   <CallIcon />
                   }
                   {location.details.summary.includes(type === power) && 
                   <ElectricIcon />
                   }
                  {location.details.summary.includes(type === water) && 
                   <WaterIcon />
                  }
                  </IconSection>
                </IconBox>
              )}
            </div>

2 个答案:

答案 0 :(得分:2)

您可以在组件状态中存储获取的类型的数组:

const [types, setTypes] = useState(location.details.summary.map(({type}) => type))

这样,您可以简单地有条件地渲染(或不渲染)图标:

 <div>
  {location.alertDetails && (
      <IconBox title={`Alerts`}>
        <IconSection>
           {types.includes('calling') && <CallIcon />} 
           {types.includes('power') && <ElectricIcon />}
           {types.includes('water') && <WaterIcon />}
        </IconSection>
      </IconBox>
    )}
  </div>

这是演示(您的所有组件都呈现为<div>,因为我没有这些):

const { render } = ReactDOM,
      { useState } = React
      
const apiData = {location:{details:{summary:[{type:'calling',icon:'phone'},{type:'power',icon:'electric'},{type:'water',icon:'water-icon'},]}}}    
      
const IconTray = ({data}) => {
  const [types, setTypes] = useState(data.location.details.summary.map(({type}) => type))
  return (
     <div>
        {data.location.details && (
            <div>
              <div>
                 {types.includes('calling') && <div>I am a CallIcon</div>} 
                 {types.includes('power') && <div>I am an ElectronIcon</div>}
                 {types.includes('water') && <div>I am a WaterIcon</div>}
              </div>
            </div>
          )}
     </div>
  )
}

render (
  <IconTray data={apiData} />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

答案 1 :(得分:0)

您可以使用地图轻松地遍历这些-

 <div>
   {location.alertDetails && location.details.summary.map(item =>{ item.icon && return  (
                <IconBox title={`Alerts`}>
                  <IconSection>
                  {location.details.summary.includes(type === calling) && 
                   <CallIcon />
                   }
                   {location.details.summary.includes(type === power) && 
                   <ElectricIcon />
                   }
                  {location.details.summary.includes(type === water) && 
                   <WaterIcon />
                  }
                  </IconSection>
                </IconBox>
    )})}
 </div>