简体   繁体   English

反应组件与箭头功能奇怪的行为

[英]react component with arrow function weird behavior

I am following the official redux tutorial with this code (it works!) 我正在使用此代码关注官方redux教程(它有效!)

const TodoList = ( {todos} ) => (
    <ul>
        { todos.map( todo => 
            <li key={todo.id}>{todo.name}</li>
        )}
    </ul>
)

I have been playing around with the syntax and this also works: 我一直在玩语法,这也有效:

const TodoList = ( {todos} ) => (
    <ul>
        { todos.map( todo => {
            return <li key={todo.id}>{todo.name}</li>
        })}
    </ul>
)

but this does not work: 但这不起作用:

const TodoList = ( {todos} ) => (
    <ul>
        { todos.map( todo => {
            <li key={todo.id}>{todo.name}</li>
        })}
    </ul>
)

Can anyone explain the difference between them and why the third one fails? 任何人都可以解释它们之间的区别以及第三个失败的原因吗?

Because the arrow function 因为箭头功能

todo => {
    <li key={todo.id}>{todo.name}</li>
}

returns nothing and you will get an array that contains undefined s ( based on the length of todos ). 什么都不返回,你会得到一个包含undefined的数组(基于todos的长度)。 For example: 例如:

const ary = [1, 2, 3].map(el => { console.log(el) })
console.log(ary) // [undefined, undefined, undefined]

You must return something in the callback of .map() 你必须在.map()的回调中返回一些东西

If the callback only contains 1 expression and returns immediately, you can omit the { } and return . 如果回调只包含1个表达式并立即返回,则可以省略{ }return

const foo = () => {
  return 'foo'
}

is equal to 等于

const foo = () => 'foo'

So now you can: 所以现在你可以:

const TodoList = ( {todos} ) => (
    <ul>
        { todos.map( todo => (
            <li key={todo.id}>{todo.name}</li>
        ))}
    </ul>
)

also the ( ) is not a must, you can omit that if you preferred: ( )也不是必须的,如果你愿意,你可以省略:

const TodoList = ( {todos} ) => (
    <ul>
      { todos.map(todo => <li key={todo.id}>{todo.name}</li>) }
    </ul>
)

The difference has to do with how you specify the body of the arrow function. 区别在于如何指定箭头函数的主体。

{ todos.map( todo => 
    <li key={todo.id}>{todo.name}</li>
)}

Is an expression within the body and by default does not need a return statement, 是一个表达式在体内,默认情况下不需要return语句,

  <ul>
    { todos.map(todo => <li key={todo.id}>{todo.name}</li>) }
  </ul>

When defined within a block, a return statement needs to be included . 在块中定义时,需要包含return语句。

Here, You nicely added a block statement , In block statement implicit return is syntactically ambiguous, now it returns undefined. 在这里,你很好地添加了一个块语句,在块语句中,隐式返回在语法上是不明确的,现在它返回undefined。 In ES6 arrow function return is implicit under some circumstances. 在ES6中,箭头函数返回在某些情况下是隐式的。 Like You added a block it made undefined. 就像你添加了一个块,它是未定义的。 You can find more detail in this post. 你可以在这篇文章中找到更多细节。

If you look at the documentation for map , you have to return a value, which will be the new value in the new array created by the map function. 如果查看map的文档,则必须返回一个值,该值将是map函数创建的新数组中的新值。 This means that return has to exist in the callback of your map function, whether stated explicitly or implicitly. 这意味着return必须存在于map函数的回调中,无论是显式还是隐式声明。

The arrow functions you have declared as a callback (eg todo => <li key={todo.id}>{todo.name}</li> ) in the first and the second example are equal. 您在第一个和第二个示例中声明为回调的箭头函数(例如todo => <li key={todo.id}>{todo.name}</li> )是相等的。 You may want to refer to different ways to declare arrow functions in the documentation here . 您可能需要在此处的文档中引用不同的方法来声明箭头函数。

In the third example however, you are returning a block of code without a return statement. 但是,在第三个示例中,您将返回一个没有return语句的代码 The default behavior of the javascript runtime is to return undefined. javascript运行时的默认行为是返回undefined。 Here are some code to demonstrate this behavior: 以下是一些演示此行为的代码:

 const test = () => { var a; /* a block of code with no return statement */ } const a = test(); console.log(a); 

Hence, the elements of the array that is returned from the map function in your third example will undefined. 因此,在第三个示例中从map函数返回的数组元素将是未定义的。 This is the main reason why your todos are not getting rendered in your list. 这是您的待办事项未在列表中呈现的主要原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM