简体   繁体   中英

Error when overriding props in React.cloneElement()

I'm new to ReactJS and recently trying to work out a sidebar component. I have two react components ( SidebarNav and SidebarNavItem ) which can be nested with each other to display a structured sidebar menu.

SidebarNav

import React, {Component, PropTypes} from 'react';

export default class SidebarNav extends Component {

    static propTypes = {
        level: PropTypes.number,
        children: React.PropTypes.oneOfType([
            React.PropTypes.object,
            PropTypes.arrayOf(PropTypes.object)
        ])
    };

    render() {

        const {level, children} = this.props;

        const currentLevel = !level ? 1 : level;

        let navClass;
        switch (currentLevel) {
            case 1:
                navClass = 'tfmenu';
                break;
            case 2:
                navClass = 'nav-second-level collpase in';
                break;
            default:
                navClass = 'nav-third-level collpase in';
        }

        return (
            <ul className={'nav ' + navClass}>
                {React.Children.map(children, element => {
                    return React.cloneElement(element, {level: currentLevel});
                })}
            </ul>
        );
    }
}

SidebarNavItem

import React, {Component, PropTypes} from 'react';

export default class SidebarNavItem extends Component {

    static propTypes = {
        title: PropTypes.string.isRequired,
        href: PropTypes.string.isRequired,
        iconClass: PropTypes.string,
        level: PropTypes.number,
        children: PropTypes.object
    };

    render() {

        const {title, href, iconClass, level, children} = this.props;

        return (
            <li>
                <a href={href}>
                    {iconClass && level === 1 && <i className={'fa ' + iconClass}></i>}

                    {level === 1 ? <span className="nav-label">{title}</span> : {title}}

                    {level === 2 && children && <span className="fa arrow"></span>}

                    {'level: ' + level}
                </a>

                {children && React.cloneElement(children, {level: level + 1})}
            </li>
        );
    }
}

The problem seems exists in the line:

{children && React.cloneElement(children, {level: level + 1})}

I'd like to explain here. The level prop is used to distinguish how deep the sidebar item lays so that different styles can be applied. When I tried to test the component with following code.

<SidebarNav>
  <SidebarNavItem href="/portal" title="Portal" iconClass="fa-home">
    <SidebarNav>
      <SidebarNavItem href="/portal/home1" title="Home1" />
      <SidebarNavItem href="/portal/home2" title="Home2" />
    </SidebarNav>
  </SidebarNavItem>
  <SidebarNavItem href="/signin" title="Signin" iconClass="fa-home" />
</SidebarNav>

I got the following errors.

Invariant Violation: Objects are not valid as a React child (found: object with keys {title}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of SidebarNavItem .

Does anyone know what's going wrong with my code? Many thanks in advance.

Error in this line {level === 1 ? <span className="nav-label">{title}</span> : {title}} {level === 1 ? <span className="nav-label">{title}</span> : {title}} . It has to be react element (or primitive value) instead of {title}

Some syntax issue with your code, { } is used for variables or functions

You can:

generate(){
    return (<span>something</span>);
}

render(){
    var abc = (<span>something</span>);
    return (
        <div>
        {abc}
        {this.generate()}
        {abc || this.generate()} 
        </div>
    );
}

You may want to take a look at those examples from react router to see how they actually implement nav side bar. Specifically the sidebar example.

react examples

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM