console.log
老鸟使用 console.log的次数是菜鸟的数十倍甚至数百倍。
Protip: Visual Studio Code snippets
使用 Visual Studio Code能够很容易创建“代码片段(snippets)” ,即快速生成常用代码块
常用的输入log
后敲Tab
键则自动补全console.log()
JavaScript Arrays
从现在开始,我们将一直使用 JavaScript 数组的函数式编程方法,比如 find, filter, 和 map。
如果使用数组的函数式编程对你来说感觉很陌生,那么至少可以看看 YouTube 视频系列的前三部分 Functional Programming in JavaScript
- 高阶函数
- Map
- Reduce 基础
Rendering Collections 渲染集合
index.js
notes声明为全局变量 ```javascript import ReactDOM from ‘react-dom’; import App from ‘./App’;
const notes = [ { id: 1, content: ‘HTML is easy’, date: ‘2019-05-30T17:30:31.098Z’, important: true }, { id: 2, content: ‘Browser can execute only JavaScript’, date: ‘2019-05-30T18:39:34.091Z’, important: false }, { id: 3, content: ‘GET and POST are the most important methods of HTTP protocol’, date: ‘2019-05-30T19:20:14.298Z’, important: true } ]
ReactDOM.render(
App.js<br />使用**map**遍历数组,返回`**li**`元素<br />箭头函数可分多行,提高代码可读性
```javascript
import React from 'react'
const App = (props) => {
const { notes } = props
return (
<div>
<h1>Notes</h1>
<ul>
{notes.map(note =>
<li>
{note.content}
</li>
)}
</ul>
</div>
)
}
export default App;
Key-attribute key属性
控制台会有提示,list的每个子元素都应该有个key。
map 方法生成的每个元素,都必须有一个唯一的键值: 一个名为key 的属性。
给li添加key:
{notes.map(note =>
<li key={note.id}>
{note.content}
</li>
)}
Anti-pattern: Array Indexes as Keys 反模式-数组索引作为key
map方法的回调函数的第二个参数i是数组索引
因此可以将索引作为li的key
notes.map((note, i) => ...)
Refactoring modules 重构模块
注意,这里是给Note组件添加key,而不是给li添加key
const Note = ({ note }) => {
return (
<li>{note.content}</li>
)
}
const App = ({ notes }) => {
return (
<div>
<h1>Notes</h1>
<ul>
{notes.map(note =>
<Note key={note.id} note={note} />
)}
</ul>
</div>
)
}
将Note组件放在单独的module中
在src目录新建components目录,在components目录新建Note.js文件
import React from 'react'
const Note = ({ note }) => {
return (
<li>{note.content}</li>
)
}
export default Note
由于这是一个 React-组件,因此我们必须导入 React
接下来在App组件中import Note, 使用相对路径,文件扩展名(.js)可以省略
import Note from './components/Note'
When the Application Breaks
当应用崩掉了怎么办?
最好的方案就是 console.log。
通过在代码不同的位置添加console.log,来寻找和排除可能出错的地方
exercise 2.1 - 2.5
复习reduce
语法
let value = arr.reduce(function(accumulator, item, index, array) {
// ...
}, [initial]);
- accumulator —— 是上一个函数调用的结果,第一次等于 initial(如果提供了 initial 的话)。
- item —— 当前的数组元素。
- index —— 当前索引。
- arr —— 数组本身。
应用函数时,上一个函数调用的结果将作为第一个参数传递给下一个函数。
因此,第一个参数本质上是累加器,用于存储所有先前执行的组合结果。最后,它成为 reduce 的结果。
如果没有初始值,那么 reduce 会将数组的第一个元素作为初始值,并从第二个元素开始迭代。
示例:
let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((sum, current) => sum + current, 0);
alert(result); // 15
course项目中使用map和reduce
import React from 'react'
const Course = ({ course }) => {
const total = course.parts.reduce((sum, item) => sum + item.exercises, 0)
return (
<>
<h1>{course.name}</h1>
{course.parts.map(item => <div key={item.id}>{item.name} {item.exercises}</div>)}
<h3>total of {total} exercises</h3>
</>
)
}
const App = () => {
const course = {
id: 1,
name: 'Half Stack application development',
parts: [
{
name: 'Fundamentals of React',
exercises: 10,
id: 1
},
{
name: 'Using props to pass data',
exercises: 7,
id: 2
},
{
name: 'State of a component',
exercises: 14,
id: 3
}
]
}
return <Course course={course} />
}
export default App
让App支持更多课程
const App = () => {
const courses = [
{
name: 'Half Stack application development',
id: 1,
parts: [
{
name: 'Fundamentals of React',
exercises: 10,
id: 1
},
{
name: 'Using props to pass data',
exercises: 7,
id: 2
},
{
name: 'State of a component',
exercises: 14,
id: 3
},
{
name: 'Redux',
exercises: 11,
id: 4
}
]
},
{
name: 'Node.js',
id: 2,
parts: [
{
name: 'Routing',
exercises: 3,
id: 1
},
{
name: 'Middlewares',
exercises: 7,
id: 2
}
]
}
]
return <>{courses.map(item => <Course key={item.id} course={item} />)}</>
}