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

I am trying to fix this lint error at line const def = (props) => { in following sample code.

const propTypes = {
prop1: PropTypes.string,
prop2: PropTypes.string,
prop3: PropTypes.string,
prop4: PropTypes.string,
prop5: PropTypes.string,
}

const abc = (props) => {
some code here }

const def = (props) => {
<div>
<div className=" ..some classes..">{abc}</div>
<div className=" ..some classes..">{t('translation/something')}</div>

<div ...>
  <someComponent 
    do something
  />

if (some condition) {
do this
} else {
do that
}

</div>

};

Any idea why i am getting this lint error?



Solution 1:[1]

You are not returning anything, at least from your snippet and comment.

const def = (props) => { <div></div> };

This is not returning anything, you are wrapping the body of the arrow function with curly braces but there is no return value.

const def = (props) => { return (<div></div>); }; OR const def = (props) => <div></div>;

These two solutions on the other hand are returning a valid React component. Keep also in mind that inside your jsx (as mentioned by @Adam) you can't have if ... else ... but only ternary operators.

Solution 2:[2]

Expected an assignment or function call and instead saw an expression.

I had this similar error with this code:

const mapStateToProps = (state) => {
    players: state
}

To correct all I needed to do was add parenthesis around the curved brackets

const mapStateToProps = (state) => ({
    players: state
});

Solution 3:[3]

You must return something

instead of this (this is not the right way)

const def = (props) => { <div></div> };

try

const def = (props) => ( <div></div> );

or use return statement

const def = (props) => { return  <div></div> };

Solution 4:[4]

The return statements should place in one line. Or the other option is to remove the curly brackets that bound the HTML statement.

example:

return posts.map((post, index) =>
    <div key={index}>
      <h3>{post.title}</h3>
      <p>{post.body}</p>
    </div>
);

Solution 5:[5]

Not sure about solutions but a temporary workaround is to ask eslint to ignore it by adding the following on top of the problem line.

// eslint-disable-next-line @typescript-eslint/no-unused-expressions

Solution 6:[6]

Possible way is (sure you can change array declaration to getting from db or another external resource):

const MyPosts = () => {

  let postsRawData = [
    { id: 1, text: 'Post 1', likesCount: '1' },
    { id: 2, text: 'Post 2', likesCount: '231' },
    { id: 3, text: 'Post 3', likesCount: '547' }
  ];

  const postsItems = []
  for (const [key, value] of postsRawData.entries()) {
    postsItems.push(<Post text={value.text} likesCount={value.likesCount} />)
  }

  return (
      <div className={css.posts}>Posts:
          {postsItems}
      </div>
  )
}

Solution 7:[7]

You use a function component:

const def = (props) => {
<div>
<div className=" ..some classes..">{abc}</div>
<div className=" ..some classes..">{t('translation/something')}</div>

<div ...>
<someComponent 
 do something
/>

if (some condition) {
do this
} else {
do that
}

 </div>

};

In the function component, you have to write a return or just add parentheses. After the added return or parentheses your code should look like this:

const def = (props) => ({
<div>
<div className=" ..some classes..">{abc}</div>
<div className=" ..some classes..">{t('translation/something')}</div>

<div ...>
<someComponent 
 do something
/>

if (some condition) {
do this
} else {
do that
}

 </div>
});

Solution 8:[8]

In my case the problem was the line with default instructions in switch block:

  handlePageChange = ({ btnType}) => {
    let { page } = this.state;
    switch (btnType) {
      case 'next':
        this.updatePage(page + 1);
        break;
      case 'prev':
        this.updatePage(page - 1);
        break;
      default: null;
    } 
  }

Instead of

default: null;

The line

default: ;

worked for me.

Solution 9:[9]

The fault is within your if statement. Had same error some time ago. I got to noticed that Within my ternary operator, I was having lines of code sepereted from each other by commas, changed to using if statement still was having same error.

I corrected it by sepereting the expressions and giving each a seperate if statement (works with ternary operator too) but in the end, I was having too many redundant codes...annoying. Have not found any solution since then

Solution 10:[10]

Firstly you must have at least one "return" before your parent div tag in your function as follows

const def = (props) => {    
   return(
       <div>
        [some other child div/codes here]    
       </div>
   )
};

Or, you can use an Arrow function in a single line as:

const def = (props) => `<div> [some other child div/codes here] </div>`

In this case "return" is not compulsory.

Secondly, you should use "Conditional (ternary) Operator".

Solution 11:[11]

In my case the eslint error was caused by an unexpected use case. Hence the code was correct, but eslint failed:

cy.customCommand().then(obj => {
      expect(obj.booleanProp).to.be.true;
    });

eslint finds an expression which is generated, but not used. That the generation produces a result (potential exception) is beyond the analyzer.

In defense of eslint: I don't expect the analyzer to anticipate this side effect. And it's foremost usecase (prevent you from unfinished code-lines) is important. So nobody to blame..

I'd suggest to just disable the warning linewise like this:

cy.customCommand().then(obj => {
      // eslint-disable-next-line no-unused-expressions
      expect(obj.booleanProp).to.be.true;
    });