Cris Abraham
Cris Abraham

Reputation: 35

React: Expected an assignment or function call and instead saw an expression in JSX

I am trying to create the left hand menu for my test application using react.

I am getting the following compilation error in the JSX of one of my classes. Is it because I am not allowed to put html elements within the {} scripts in JSX? If so how can this be changed to make it work?

./src/components/LeftNav.js

Line 10: Expected an assignment or function call and instead saw an expression no-unused-expressions

Line 12: Expected an assignment or function call and instead saw an expression no-unused-expressions

The component I am getting the error in is the following.

import React, { Component } from 'react';

import LeftNavItem from './LeftNavItem';

class LeftNav extends Component {
    render() {
        return (
            <ul>
                {this.props.leftNav.map((navItem) => {
                    <li className="parent_wrapper">{navItem.title}</li>
                    navItem.subMenu.map((subMenuItem) => {
                        <LeftNavItem key={navItem.id} navItem={navItem.subMenu} />
                        })
                    })
                }
            </ul>
        )
    }
}

export default LeftNav;

Line 10 is

<li className="parent_wrapper">{navItem.title}</li>

Line 12 is

<LeftNavItem key={navItem.id} navItem={navItem.subMenu} />

The props for this class is

leftNav: [
      {
        id: 1,
        title: 'System Admin',
        active: false,
        subMenu: [
          {
            id: 2,
            title: '',
            active: false
          },
          {
            id: 3,
            title: '',
            active: false
          },
          {
            id: 4,
            title: '',
            active: false
          },
          {
            id: 5,
            title: '',
            active: false
          },
          {
            id: 6,
            title: '',
            active: false
          },
          {
            id: 7,
            title: '',
            active: false
          },
          {
            id: 8,
            title: '',
            active: false
          },
          {
            id: 9,
            title: '',
            active: false
          }
        ]
      },
      {
        id: 10,
        title: 'Reports',
        active: false,
        subMenu: [
          {
            id: 11,
            title: 'Reports',
            active: false
          },
          {
            id: 12,
            title: 'Dashboard',
            active: true
          },
          {
            id: 13,
            title: 'Templates',
            active: false
          }
        ]

LeftNavItem class is as below

import React, { Component } from 'react'

export default class LeftNavItem extends Component {
    render() {
        return (
            <li><a href="">{this.props.navItem.title}</a></li>
        )
    }
}

Thank you!

Upvotes: 2

Views: 2210

Answers (5)

ravibagul91
ravibagul91

Reputation: 20755

I think you just forgot to return from map. You can use Fragment to wrap your outer map return.

{this.props.leftNav.map((navItem) => {
    return <React.Fragment key={navItem.id}>  //Provide key here
    <li className="parent_wrapper">{navItem.title}</li>
    {navItem.subMenu.map((subMenuItem) => {
        //Here you should use subMenuItem
        return <LeftNavItem key={subMenuItem.id} navItem={subMenuItem} />  
      })
    }
    </React.Fragment>
})}

Demo

Note: Read more about Keyed Fragments

Upvotes: 3

Andy
Andy

Reputation: 63524

Because you're using curly braces in the maps you need to explicitly use return. In addition, you'll also need to wrap your inner code in another element like a div or a React fragment (which I've used here) as multiple children must be enclosed within a parent element.

<ul>
  {this.props.leftNav.map((navItem) => {
    return (
      <Fragment>
        <li className="parent_wrapper">{navItem.title}</li>
        {navItem.subMenu.map((subMenuItem) => {
          return <LeftNavItem key={navItem.id} navItem={navItem.subMenu} />
        })}
      </Fragment>
    );
  })}
</ul>

Alternatively you could replace those curly braces with parentheses and then the return is implied. You still need the parent element tho.

<ul>
  {this.props.leftNav.map((navItem) => (
    <Fragment>
      <li className="parent_wrapper">{navItem.title}</li>
      {navItem.subMenu.map((subMenuItem) => (
        <LeftNavItem key={navItem.id} navItem={navItem.subMenu} />
      ))}
    </Fragment>
  ))}
</ul>

Upvotes: 2

Andrei Todorut
Andrei Todorut

Reputation: 4526

If you have multiple components to return then wrap them in a single HTMLElement or use React Fragments. https://reactjs.org/docs/fragments.html

On map you always have to return something.

Also wrap all your javascript code into {}

import React, { Component } from 'react';

import LeftNavItem from './LeftNavItem';

class LeftNav extends Component {
    render() {
        return (
            <ul>
                {this.props.leftNav.map((navItem) => {
                  return (
                    <li className="parent_wrapper">{navItem.title}
                    {navItem.subMenu.map((subMenuItem) => {
                        return <LeftNavItem key={navItem.id} navItem={navItem.subMenu} />
                        })}

                    </li>
                  )
                })}
            </ul>
        )
    }
}

export default LeftNav;

Upvotes: 0

ZSnake
ZSnake

Reputation: 158

You're not returning anything from your map function. You can wrap your content in parentheses instead of curly braces.

        <ul>
            {this.props.leftNav.map((navItem) => (
                <li className="parent_wrapper">{navItem.title}</li>
                navItem.subMenu.map((subMenuItem) => {
                    <LeftNavItem key={navItem.id} navItem={navItem.subMenu} />
                    })
                })
            )
        </ul>

Upvotes: 0

Clarity
Clarity

Reputation: 10873

You need to return values from map:

 {
  this.props.leftNav.map(navItem => {
    const navItems = navItem.subMenu.map(subMenuItem => {
      return <LeftNavItem key={navItem.id} navItem={navItem.subMenu} />;
    });
    return (
      <>
        <li className="parent_wrapper">{navItem.title}</li>;
        {navItems}
      </>
    );
  });
}

Upvotes: 0

Related Questions