-2

I usually always write an arrow function and when I need it to be multi-lined then I do "{}". However, I am watching a tutorial, and in it, he is writing this useEffect function:

  useEffect(() => {
    if (chatId) {
      db.collection("chats")
        .doc(chatId)
        .collection("messages")
        .orderBy("timestamp", "desc")
        .onSnapshot(snapshot => (
          setMessages(snapshot.docs.map(doc=>({
            id:doc.id,
            data:doc.data()
          })))
        ));
    }
  }, []);

notice after "snapshot" he has "=> (" not "=> {" and also snapshot.docs.map(doc=>({ where there is a "({" rather than just a "{". Someone help me understand what I am missing here?

  • When your arrow function returns an object literal you need to wrap it in parenthesis so the transpiler can distinguish it from a function. – The Head Rush Dec 25 '20 at 16:55
  • Explained in the [documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) which is generally the best place to start – charlietfl Dec 25 '20 at 16:59

4 Answers4

1

Each use of parenthesis and curly brackets has a different result based on the purpose. Using curly brackets by themselves will not return a result, which may be desired or you can use return to return a result.

useEffect(() => {
  // If I want to return a result, I need to use the return keyword
})

If you want to return a result immediately from the function, you can either place the returned result immediately after the => or wrap it in parenthesis.

// These are equivalent
snapshot => setMessages()
snapshot => (setMessages())

Finally, if you want to return an object from the function, you wrap the curly brackets with parenthesis. This indicates that you want to return a value rather than returning nothing like the first example.

doc => ({
  id:doc.id,
  data:doc.data()
})
Mark Skelton
  • 3,663
  • 4
  • 27
  • 47
0

When you run multiple commands inside callback function, you need to use {}.

Actually, snapshot => (setMessages(...)) is equivalent with snapshot => {return setMessages(...)}

Prime
  • 2,809
  • 1
  • 7
  • 23
0
  • Traditional Function
function (a) {
    return a + 100;
}
  • Remove the word "function" and place arrow between the argument and opening body bracket
(a) => {
    return a + 100;
}
  • Remove the body brackets and word "return" -- the return is implied.
(a) => a + 100;
  • Remove the argument parentheses
a => a + 100;
Smart Solutions
  • 869
  • 2
  • 10
  • 30
0

The grammar of an arrow functions allow for either a block { } or an expression. Since an object literal (an expression) is also { } there is an ambiguity between a block an object literal. So the standard dictates that { } is always a block in this scenario.

Using ({ }) allows you to wrap the object literal expression with a parenthesis expression which just evaluates to the object literal. In other words, a handy way to bypass the ambiguity restriction.

Of course, the reason that it allows a block ({ }) in the first place is to offer different semantics to its expression counterpart. A block would mean that you are writing a function body, e.g. multiple statements is possible as is using a return statement. Its expression counterpart just allows for one expression.

MinusFour
  • 13,913
  • 3
  • 30
  • 39