React - iterating through an array and Events

Viewed 78

Suppose I have an array of cars that I use to set an inital state:

const [ carState, setCarstate ] = useState({
    cars: [
      {model: 'Ferarri', yearOfFabrication: 2001},
      {model: 'Toyota', yearOfFabrication: 2005},
      {model: 'Tesla', yearOfFabrication: 2017},
      {model: 'Ford Mustang', yearOfFabrication: 2003}
    ]
});

Can someone please explain why the below code is not showing any cars?

{carState.cars.map(car => {<Car model={car.model} age={car.yearOfFabrication}/>})}

and this one it's working?

{carState.cars.map(car => <Car model={car.model} age={car.yearOfFabrication}/>)}

The only difference between those two piece of code is, that the first encapsulates the return in a block of code. So perhaps this is not a React question but rather an ES6 arrow functions question?

Also, consider the below component which is passing a method reference through props:

<Input handler={() => changeCarNameHandler}/>

This doesn't work as expected, as it should call the changeCarNameHandler method upon a change event, here's the component code:

const input = props => {
    return(
        <input onChange={props.handler}></input>
    )
}

However, this is working

<Input handler={(event) => changeCarNameHandler(event)}/>

Can someone please clarify this? If you can also provide some resources where I can read more about this, that would be appreciated.

2 Answers
{carState.cars.map(car => {<Car model={car.model} age={car.yearOfFabrication}/>})}

If you're adding curly braces after arrow ( => ) then you have to explicitly add a return statement for rendering your Car component so it looks-

{carState.cars.map(car => { return (<Car model={car.model} age={car.yearOfFabrication}/>)}
)}

and

{carState.cars.map(car => <Car model={car.model} age={car.yearOfFabrication}/>)}

Above code works without return because it doesn't have curly braces after arrow( => ) so a single line code without a curly brace implicitly refers to a return statement in javascript

Naturally functions without a return statement return undefined by default.

This changes with arrow functions, which can potentially have an implicit return.

In the case that your arrow function has a single expression as the function body, that expression will be executed, and the resulting value will be implicitly returned when the function is called.

const simple = () => 'code'
simple()    // returns 'code'

For an arrow function to have an implicit return, an expression is required. But sometimes we need to use statements (if-else etc).

In a programming language, an expression returns or is replaceable with a value. A statement will execute some code without a resulting value.

For arrow functions to contain statements the function body must be surrounded by {curlies}. And as soon as you have curly braces surrounding your function body, returns are no longer implicit -- for either statements or expressions.

const simple = () => { return 'code' }
simple()     // returns 'code'

const broken = () => { 'code' }
broken()       // returns undefined
Related