【问题标题】:Render components conditionally, based on items of deeply nested array基于深度嵌套数组的项目有条件地渲染组件
【发布时间】:2020-06-04 03:15:17
【问题描述】:

我有一个 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>

【问题讨论】:

  • @YevgenGorbunkov 是的!
  • @YevgenGorbunkov 将其作为道具接收

标签: javascript reactjs typescript


【解决方案1】:

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

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>

这是演示(所有组件都呈现为&lt;div&gt;,因为我没有这些):

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')
)
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"&gt;&lt;/script&gt;&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"&gt;&lt;/script&gt;&lt;div id="root"&gt;&lt;/div&gt;

【讨论】:

  • 我收到一个错误,其中钩子声明为 object is possibly null or undefined for location.details in useState(location.details.
  • 这本来可行,但我忽略了我的应用程序当前架构中的一些东西,迫使我采取另一种方法。感谢您的回答以及关于.includes()的澄清!
  • @Josh : 不客气,如果(希望不是;)您在当前架构的某个地方遇到挫折,我们会很乐意支持您
【解决方案2】:

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

 <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>

【讨论】:

  • 在渲染多个元素时分配key属性是recommended。在渲染多个统一元素时,您确实可以从map() 中受益,在您的回答中它不会减少代码行,而且会增加不必要的开销。
猜你喜欢
  • 2021-07-29
  • 2019-05-12
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-20
  • 2018-09-13
  • 2019-02-18
相关资源
最近更新 更多