如何从json对象渲染react组件?

时间:2019-03-21 22:09:45

标签: javascript reactjs

我制作了一个菜单组件,该菜单组件接受带有所有菜单项的json对象。 对于图标,我使用react-icons/io。 json对象是这样的:

const menus = {
    Item1: { buttonText: 'Item 1 text', icon: { IoLogoAndroid }, path: 'item 1 path' },
    Item2: { buttonText: 'Item 2 text', icon: { IoLogoAndroid }, path: 'item 2 path'},
};

这是菜单功能,它将菜单项呈现为按钮:

const buttons = Object.keys(this.props.menus).map((menu) => {
        return (
            <a key={menu} href={this.props.menus[menu].path}
                onClick={this.changeMenu.bind(this, menu)}>
                {...this.props.menus[menu].icon} <- fail here
                {this.props.menus[menu].buttonText}
            </a>
        );
    }) 

我尝试了多种方法来渲染图标,但是对于如何工作我一无所知。不知道这是否有可能。有指针吗?

3 个答案:

答案 0 :(得分:1)

我当时正在处理一个类似的项目,并且设法使它像这样的语法正常工作

我这里有一个对象数组(如您的对象)

links: [
      {
      name: 'Frontend',  
      link: 'https://github.com/Thomas-Rosenkrans-Vestergaard/ca-3-web', 
      icon: <FaCode size={40} />,
      id: 1
      }, 
      {
      name: 'Backend',
      link: 'https://github.com/Thomas-Rosenkrans-Vestergaard/ca-3-backend',
      icon: <FaCogs size={40}/>,
      id: 2
      },
      {
      name: 'Mobile',
      link: 'https://github.com/Thomas-Rosenkrans-Vestergaard/ca-3-app',
      icon: <FaMobile size={40} />,
      id: 3
       }] 

然后我通过映射渲染我的组件,在那里我将整个对象作为道具传入

const projects = this.state.projects.map((project, i) => {
  return(
 <Project key={`Project key: ${i}`} project={project}  />
  )
})

然后我使用objectdestructing获得道具

 const { logo } = this.props.project

然后就可以显示

//in my case I use antd framework, so I pass the FAIcon component in as a prop 

 <Meta
    avatar={logo}
    title={title}
    description={description}
  />

我想您可以通过将整个菜单对象作为道具传递,然后访问图标来做同样的事情?

答案 1 :(得分:1)

您需要更改以下内容:

icon: <IoLogoAndroid />

然后在代码中(删除点差运算符):

this.props.menus[menu].icon

还有一些重构建议。

  • 您真的需要一个对象对象吗?为什么不使用对象数组,其中每个项目都有一个“名称”道具?迭代起来会更容易,因为您可以直接从地图访问道具,而无需使用对象键。
  • 您正在创建一个按钮列表,因此您也应该同时具有ul和li标签。
  • 考虑仅传递对onClick的引用,例如:

    onClick={this.changeMenu}
    

如果需要传递数据,则应使用数据集。传递名称/路径,然后在更改处理程序中找到它,以避免在每次重新渲染时重新绑定。

包含一系列对象的重构建议

changeMenu = e => {
    const { menus } = this.props;
    const { menuName } = e.target.dataset;
    const menu = menus.find(menu => menu.name === menuName);
    // Do something with menu
    return;
  };

  renderMenu() {
    return (
      <ul>
        {this.props.menus.map(menu => (
          <li key={menu.name} style={{ listStyle: "none" }}>
            <a
              data-menu-name={menu.name}
              href={menu.path}
              onClick={this.changeMenu}
            >
              {menu.icon}
              {menu.buttonText}
            </a>
          </li>
        ))}
      </ul>
    );
  }

答案 2 :(得分:0)

如果要从定义对象的位置导入图标,则只需对其进行标记<IoLogoAndroid/>;,因此react知道它将其视为要渲染的元素。

const menus = {
    Item1: { buttonText: 'Item 1 text', icon: <IoLogoAndroid/> , path: 'item 1 path' },
    Item2: { buttonText: 'Item 2 text', icon: <IoLogoAndroid/>, path: 'item 2 path'},
};

然后直接调用它(删除...

<a key={menu} href={this.props.menus[menu].path}
    onClick={this.changeMenu.bind(this, menu)}>
    {this.props.menus[menu].icon}
    {this.props.menus[menu].buttonText}
</a>

或者,如果您不想在对象定义中对其进行标记,则可以只调用React.createElement

<a key={menu} href={this.props.menus[menu].path}
    onClick={this.changeMenu.bind(this, menu)}>
    {React.createElement(this.props.menus[menu].icon)}
    {this.props.menus[menu].buttonText}
</a>

以下是显示两个实现https://codesandbox.io/s/pmvyyo33o0

的示例