This question already has answers here:
Arrow function without curly braces
(9 answers)
Closed 4 years ago.
We create presentational component or stateless component like this
const MyComponent = () => {
return(<div>my component</div>)
}
but I'd seen this
const MyComponent = () =>
<div>
<h1>head</h1>
my component
</div>
so now I'm confused when the braces is needed when using es6's arrow function.
This confused me on when rendering a list using map
shorter version
<div>
{map(o =>
<div>{o.name}</div>
)}
</div>
longer version
<div>
{map(o => {
return(<div>{o.name}</div>)
})}
</div>
Both are correct, but why write longer?
{map(o => // without curly brackets
<div>{o.name}</div> // this will be returned implicitly
)}
{map(o => { // with curly brackets
return <div>{o.name}</div> // you need to return explicitly
}
)}
If you do curly brackets ,
You have to explicilty return the data ,
When to use which one?
When you have mutliple line of execution you need to do curly brackets and return from it
But if you have single line of execution, that you need to return , then there is no need of curly brackets and return , it will return implicitly.
Same as If condition
if(true)
// do this for single line
else
// do this for single line
if() {
// do this for multiple line
} else {
// do this for multiple line
}
Arrow functions work both way to provide you with a bit of versatility. Say you need to perform some logic inside your function before you return, in this case you would need to add curly braces, i.e say you need to extract the name of a list of users, but you want to append their title.
let users = [new User(), ... ];
//...
let withTitle = users.map(p => {
const title = getTitle(p); // automagically returns Mr, Mrs, etc
return `${title} ${p.fullName}`
});
// withTitle => ['Mr Ricky Bobby', 'Mr Ron Burgundy']
Now, you can declare a function that does the work for you, and use the shorthand version of the arrow function. like so.
const extractWithTitle: (user) => {
const title = getTitle(p); // automagically returns Mr, Mrs, etc
return `${title} ${p.fullName}`
}
let withTitle = users.map(p => extractWithTitle(p));
// withTitle => ['Mr Ricky Bobby', 'Mr Ron Burgundy']
Now, an even shorter way to approach this would be to pass a reference to the function.
users.map(extractWithTitle);
Both are correct, but why write longer?
You basically need to use the longer version if you need to add more sentences in you arrow function other than the jsx component.
E.g.
<div>
{map(o => {
const name = "My name is: " + o.name;
return(<div>{name}</div>)
})}
</div>
Otherwise, you may use the short version.
Related
This question is intended as canonical duplicate target for questions about problems that stem from confusing the single-line/expression arrow function body syntax with automatic return with their multi-line/block version.
I have an arrow function to add two numbers, but when I call it, it returns undefined. Why?
const add = (a, b) => {
a + b
}
console.log(add(1, 2)) // expected: 3, actually: undefined
Alternative question:
My React component is supposed to render list items using map, but the list stays empty. Why?
<ul>
{list.map(item => {
<li>
{item.name}
</li>
})}
</ul>
Arrow functions support two different styles of bodies: expressions and blocks.
If a single expression is provided (e.g. a + b) without braces { } around it, that expression is automatically returned:
const add = (a, b) => a + b
If a block enclosed by { } is provided, it works like a regular function body and requires a dedicated return statement to return a value:
const add = (a, b) => {
return a + b
}
Single-expression bodies are often used to write simple functions in a concise way which execute one operation or condition, as in the following examples:
if (users.every(user => user.age >= 18)) { /* ... */ }
const emails = users.map(user => user.email)
const titleCased = string.replace(/\b\w/g, s => s.toUpperCase())
// in the following example, the return value is irrelevant
setTimeout(() => doStuff(1, 2, 3), 1000)
In most other cases, especially if you want to have multiple statements, loops or conditions in your function body, a block is used.
Note that you can have a function body spanning multiple lines even without a block if it is still a single expression, but if you would like to turn it into a block for readability reasons, you must not forget to add return (unless your function isn't supposed to return anything).
Now, this is the reason why your add function is returning undefined - it neither has a single-expression body (the { } make it a block) nor does it have any return statement in its body. So, what happens is that a + b is evaluated, but the result isn't used for anything - it is thrown away and execution continues, reaching the end of the function and returning without any return value since none was given, i.e. returning undefined.
In the React case, the problem is the same. You are embedding the return value of a .map call, which should be an array of further content to render, but because your callback is not returning any value, you are mapping the items to several undefined values and rendering that at the end.
There is another twist here though: you may often need multiple lines in the element(s) that you return from a function like a map callback, but you will find that neither of the following two options looks quite clean:
<ul>
{list.map(item => <li>
{item.name}
</li>)}
</ul>
<ul>
{list.map(item => {
return <li>
{item.name}
</li>
})}
</ul>
Instead, what is usually done is enclosing the expression in parentheses ( ). It is a still a single expression at the end, avoiding the need for an extra return statement, but is a lot nicer to work with:
<ul>
{list.map(item => (
<li>
{item.name}
</li>
))}
</ul>
For more information about arrow functions in general, see here. To read about other differences between arrow functions and regular functions (such as different behavior of this), see here.
Arrow functions return code in these cases:
Case 1: When it's written inline like below
/* notice that this is an implicit return
and we don't need a return statement here as the code is
in the same line after the => */
const add = (a, b) => a + b
console.log(add(1, 2)) // expected: 3
Case 2: When it's written with round brackets () like this
Case 2 - example 1
/* notice the round bracket here.
You will use this when you have a
block of code here unlike case 1
where you had a single line to return */
const add = (a, b) => ( // this is round bracket, no return needed
a + b
// and other blocks of code. Look at the below JSX example for
// for this case
)
console.log(add(1, 2)) // expected: 3
The above example is similar to first case 2 - example 1, but this case is more suitable for a single block of code mostly for JSX like below
Case 2 - example 2
<ul>
{list.map(item => ( // this is round bracket, no return needed
<li>
{item.name}
</li>
)}
</ul>
Case 3: With an explicit return statement when you use curly braces like this
const add3 = (a, b) => { // curly braces + return statement
return a + b;
};
const res3 = add3(1, 2);
console.log(res3); // 3
In your case, notice you're mixing both cases 2 and 3. Meaning, you are using curly braces as defined in case 3 and also not using return keyword then like in case 2 which is the reason it doesn't work.
Code : https://codesandbox.io/s/javascript-forked-ckjg69?file=/src/index.js
This question already has answers here:
Curly Brackets in Arrow Functions
(3 answers)
Closed 1 year ago.
I encountered an issue while working on a project and I noticed that it was as a result of the curly braces in my function... quick example
const array1 = [1,2,3,4,5,6];
const array2 = [2,4,6];
const isPresentInBothArrays1 = array2.every((number)=>{
array1.includes(number);
});
console.log(isPresentInBothArrays1) //prints false;
const isPresentInBothArrays2 = array2.every((number)=>array1.includes(number));
console.log(isPresentInBothArrays2) //prints true;
why does isPresentInBothArrays1 with curly braces return false and IsPresentInBothArrays2 without curly braces return true?
It's because of the arrow function syntax, If you write something like this:
(param1, param2) => {//some expression}
is equivalent to this:
function f(param1, param2) {
// some expression
}
and because it does not have an explicit return statement it will return undefined by default.
However, if you omit the curly brackets and put a single expression that would be a shortcut and will return the value of that expression as the return value of the function.
So as for your question in the first form, it will return undefined from the function which evaluates to false and is not what you desire, but the second form correctly returns a boolean indicating the existence of the value.
you need to add return if you use curly braces:
const array1 = [1,2,3,4,5,6];
const array2 = [2,4,6];
const isPresentInBothArrays1 = array2.every((number)=>{
return array1.includes(number);
});
console.log(isPresentInBothArrays1) //prints true;
const isPresentInBothArrays2 = array2.every((number)=>array1.includes(number));
console.log(isPresentInBothArrays2) //prints true;
If you omit curly braces, arrow function will implicitly return the result of the expression after the =>.
However, if you use curly braces, you'll need to write return in order to make it return something, otherwise, it will return undefined.
So, in this particular case, you'll need to write:
const isPresentInBothArrays1 = array2.every(number => {
return array1.includes(number);
});
In case you want to have curly brackets for whatever reason.
I'm experimenting with Array.map() and got this little snippet, which does perform as intended:
let cities = ["Buenos Aires", "Santa Fe", "Mar del Plata", "Mar de las Pampas"];
function urlify(string) {
return string.split(" ").join("-").toLowerCase();
}
function functionalUrl(elements) {
return elements.map( element => urlify(element) );
}
console.log(functionalUrl(cities));
// ['buenos-aires', 'santa-fe', 'mar-del-plata', 'mar-de-las-pampas' ]
However, if I replace
return elements.map( (element) => urlify(element) );
with
return elements.map( (element) => { urlify(element); } );
(i.e., add parentheses and curly braces) it returns
[undefined, undefined, undefined, undefined]
I don't understand such behavior, as the curly braces/parentheses form is supposed to be "correct", and taking them away (I thought?) is just allowed in the specific case of a single-argument function...
What am I missing here?
Thanks!
elements.map( (element) => { urlify(element); } );
When you do the above code, you are creating the function body (assuming there are more lines of code to be included) and it expects the 'return' keyword, but if you are returning a single value (the result of one single computation), in your case
elements.map( (element) => urlify(element) );
then you don't have to specify the return keyword.
So the correct code for the second scenario using braces will be
elements.map( (element) => {return urlify(element)} );
The first one is a shorthand syntax not using the return keyword, also if you just have only one parameter you don't have to wrap the parameter inside the parenthesis.
So the more concise way should be
elements.map( element => urlify(element) );
This question already has answers here:
Arrow function without curly braces
(9 answers)
Closed 4 years ago.
Learning React and trying to cheat off this codepen. I do not understand 2 things about the map function in FormCard.
Why does this .map function have a return statement, I did not see a return on other examples
Why does the arrow function use curly braces instead of parentheses like the previous arrow function
const FormCard = (props) => (
const FormCard = (props) => (
<div>
{
DATA.map((props) => {
return <div style={{...largebox, ...flex}} key={props.id}>
<div style={{...Photo,backgroundImage: `url(${props.photo})`}}></div>
<div>
<Author author={props.author}/>
<Something bio={props.bio}/>
<AdBox adpic={props.adpic} />
<IconBox />
</div>
</div>
})
}
</div>
)
These are two different ways of returning from arrow functions.
The implicit return:
If the body starts with an expression and not with a { is seen as a value to be returned.
[0,1,2,3,4,5,6].map(v => ({value:v})); // gives an array of objects with value set to v.
[0,1,2,3,4,5,6].map(v => v*v)// gives an array of squares of the initial array.
the explicit return:
If the body starts with a {, it seen as the body of the function, and a return statement is expected to return.
[0,1,2,3,4,5,6].map(v => { return {value:v}}); // gives an array of objects with value set to v.
[0,1,2,3,4,5,6].map(v => { return v*v})// gives an array of squares of the initial array.
Generally,
array.map((arg) => { return actionWith(arg) })
array.map((arg) => actionWith(arg))
Are equal, thus developers shrink their functions if they have returns only
This question already has answers here:
Arrow function without curly braces
(9 answers)
Curly Brackets in Arrow Functions
(3 answers)
Closed 4 years ago.
What's the difference between these two in javascript? what does it mean in scripting?
const Test1 = () => {
console.log('test1')
}
const Test2 = () => (
console.log('test2')
)
The "basic" form is with curly braces, just like regular functions:
() => {
...
}
However, arrow functions allow one special case shorthand:
() => plain expression
If you don't use curly braces, you may use one plain expression instead, with an implicit return. I.e. these two are equivalent:
() => { return 42; }
() => 42
So your version using parentheses counts as the single expression version and the return value of console.log will be returned (which is undefined either way though), whereas it won't on the version using curly braces.
Second example used to simplify returning of function, but in this case you can use only one expression, so you cannot write large of code. Try to run this example to better understand:
const Test1 = () => {
'test1'
}
console.log(Test1())
const Test2 = () => ( test = 'test4')
console.log(Test2())
Also this declaration method uses to simplify returning objects:
const Test3 = () => ({ a: 1, b: 2 });
console.log(Test3());