将元素列表推送到React中的组件

问题描述 投票:1回答:2

我想构建类似于此图像中的侧边栏组件:sidebar-components

而不是通过道具将带有文本值的子组件作为对象传递,我想为列表中每个元素中的每个键值对创建一个单独的组件。例如:如果列表中有3个元素,则列表中每个元素应有3个组成部分。

到目前为止是我的代码:

sidebarcomponents.js:

import React from 'react'

function SidebarComponents({ name, title, selected, onSelect }) {
  const style = {
    cursor: 'pointer'
  }

  return (
    <div
      name={name}
      title={title}
      style={style}
      onClick={() => {
        if (onSelect) onSelect(name)
      }}
    >
                   
    </div>
  )
}

export default SidebarComponents

sidebar.js:


import React, { useEffect, useState } from 'react'
import SidebarComponents from '../../components/Sidebar1/Sidebar'

function Sidebar({ onChange }) {
  const [selectedComponent, setSelectedComponent] = useState({
    componentsName: [
      { name: 'Overview', title: 'Overview' },
      { name: 'SPO2', title: 'SPO2' }
    ]
  })

  return (
    <div>
      {selectedComponent.componentsName.map(componentsName => {
        return (
          <SidebarComponents
            name={componentsName.name}
            title={componentsName.title}
          />
        )
      })}
    </div>
  )
}

export default Sidebar

我如何更改代码以映射列表的子组件,而不是表示它们的对象的列表?

我希望我的问题清楚。

reactjs components
2个回答
0
投票
@ shubham-khatri的答案是正确的:您需要在组件内部包含文本。

[下面是使用render propshooks的更深入的解决方案-我建议阅读链接文档,因为钩子和渲染道具很棒。请注意,钩子仅从React 16.8开始可用。

简单来说,在下面的示例中,边栏使用父组件render提供的App道具进行渲染。在renderSidebarComponent道具中,该函数表示要渲染TitleName组件。 name函数的map用作onClick处理程序的参数,并且无需将所选的组件对象传递到侧边栏即可将selected设置为truefalse。 >

[如果要提供侧边栏可以渲染的组件的主列表,然后将这些集合中的哪一个传递给道具,则必须过滤componentsName数组,以便仅道具中提供的那些对于SidebarComponent

import React from 'react' import ReactDOM from 'react-dom' /** * Title component * @param {string=''} props.title */ const Title = ({ title = '' }) => <h2>{title}</h2> /** * Name component * @param {string=''} props.name */ const Name = ({ name = '' }) => <div>{name}</div> /** * SidebarComponent styles */ const style = { cursor: 'pointer' } /** * SidebarComponent classes */ const classes = { selected: { backgroundColor: '#00ff00' } } /** * @func SidebarComponent * @param {string=''} name * @param {function} onClick * @param {boolean=false} selected * @param {string=''} title * @returns {React.Node} react component that returns a div * containing two other components: Title and Name */ const SidebarComponent = ({ name = '', onClick, selected = false, title = '' }) => ( <div onClick={onClick && onClick} style={{ ...style, ...(selected ? classes.selected : {}) }} > <Title title={title} /> <Name name={name} /> </div> ) /** * @func Sidebar * @param {Array[{title: string, name: string}]} componentsName an * arry of components to render inside the sidebar, as SidebarComponents * @param {function} renderProp render function that dictates * what to render inside of the sidebar * @returns {Node} returns the calling of the renderProp function */ const Sidebar = ({ componentsName, render }) => { const [selectedComponentName, setSelectedComponentName] = React.useState(null) const handleClick = name => setSelectedComponentName(name) return ( <div id="sidebar"> {render({ selectedComponentName, handleClick })} </div> ) } /** * An array of the components to render inside the Sidebar */ const componentsName = [ { name: 'Overview', title: 'Overview' }, { name: 'SPO2', title: 'SPO2' } ] /** * @func App * @returns {React.Node} a react component that renders the sidebar */ const App = () => ( <Sidebar render={({ selectedComponentName, handleClick }) => componentsName.map(({ name, ...props }, index) => ( <SidebarComponent selected={name === selectedComponentName} key={`sidebar-component-${index}`} onClick={() => handleClick(name)} {...{ name, ...props }} /> )) } /> ) ReactDOM.render(<App />, document.getElementById('container'))

演示

https://codesandbox.io/s/react-playground-wnxer?file=/index.js

在此演示中,您可以单击任一菜单项,然后看到所选的项目将背景色更改为绿色。


0
投票
您需要在组件内部的DIV中呈现名称,而不能将其作为对div的支持,例如
© www.soinside.com 2019 - 2024. All rights reserved.