《react.js小书》读书笔记三

  • cindy Liu
  • 27 Minutes
  • January 11, 2019

《react.js》小书非常基础,适合入门新手,非常好理解,规定自己三天时间内阅读完并确保最基本的知识都掌握了,将一些平时回忽略的注意点做了小笔记和总结

《react.js小书》读书笔记一
《react.js小书》读书笔记二
在线阅读:http://huziketang.com/books/react/
在线OJ试题:http://scriptoj.mangojuice.top/problemsGroups/593a2e29b3838c385539fa4f

第三阶段

高阶函数

就是一个函数,传给它一个组件,它会返回一个新的组件

1
const NewComponeent = higherOrderComponent(OldComponent)

高阶组件是一个函数,而不是组件,他接受一个组件作为参数,返回一个新的组件

1
2
3
4
5
6
7
8
9
10
11
import React, { Component } from 'react'

export default (WrappedComponent) => {
class NewComponent extents Component {
// 可以做很多自定义逻辑
render () {
return <WrappedComponent />
}
}
return NewComponent
}

现在给NewComponent 做一些数据启动工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

import React, { Component } from 'react'
export default (WrappedComponent, name) => {
class NewComponent extents Component {
constuctor (){
super()
this.state={ data:null }
}

componentWillMount () {
let data = localStorage.getItem(name)
this.setState({ data})
}

render () {
return <WrappedComponent data={this.state.data}/>
}
}
return NewComponent
}

高阶组件的作用其实是为了组件之间的代码复用,组件可能有着某些相同的逻辑,把这些逻辑抽离出来,放到高阶组件中进行复用。高阶组件内部的包装组件和被包装组件之间通过props传递数据。(其实就是设计模式中的装饰者模式)

context

某个组件只要往自己的context里面放了某些状态,这个组件之下的所有子组件都直接访问这个状态而不需要通过中间件的传递。(只有子组件可以访问,父组件不行)

redux

redux和react-redux不是同一个东西,redux是一种架构模式,是flux架构的变种,可以同react和vue等库结合,而react-redux就是redux与react.js结合起来的一个库

store

store是一个集合,使用createStore来专门生产state 和 dispatch,包含了如下几种方法:

1
2
3
4
5
6
7
8
9
10
function createStore (state, stateChanger) {
const listeners = []
const getState = () => state
const subscribe = (listener) => listeners.push(listener)
const dispatch = (action) => {
stateChanger(state, action)
listeners.forEach((listener) => listener())
}
return { getState, dispatch, subscribe }
}

纯函数:

函数的返回结果只依赖于它的参数
1
2
3
4
5
6
7
8
9
const a = 1
const foo = (b) => a+b
foo(2) // 3
//foo 不是一个纯函数,因为返回结果依赖于外部变量a


const foo2 = (x, b) => x + b
foo2(1,2) //3
//foo2是一个纯函数,因为只依赖于参数
函数执行过程没有副作用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
consst a = 1
const foo = (obj, b) => {
return obj.x + b
}
const counter = { x : 1 }
foo(counter,2)
counter.x // 1
// foo 是一个纯函数,计算前后的counter并不会发生任何改变


const a = 1
const foo = (obj, b) => {
obj.x = 2
return obj.x + b
}
const counter = { x: 1 }
foo2(counter, 2) // => 4
counter.x // => 2
//foo2不是纯函数,计算前后counter发生了改变。

reducer

createStore接受一个叫reducer的函数作为参数,这个函数规定是一个纯函数,他接受两个参数,一个是state,一个是action。如果没有传入state或者state为null,那么他就会返回一个初始化的诗句,如果有传入state的话,那么就会根据action来修改数据,如果不能识别action,就不会产生新的数据,而是把state原封不动返回。

回顾redux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function createStore( stateChanger) {
let state = null
const listeners = []
const subscribe = (listener) => listeners.push(listener)
const getState = () => state
const dispatch = (action) => {
state = stateChanger(state, action) // 覆盖原对象
listeners.forEach((listener) => listener())
}
dispatch({}) // 初始化 state
return {
getState,
dispatch,
subscribe
}
}
1
if (newAppState === oldAppState) return
1
2
3
4
5
6
7
8
9
10
11
12
13
//定义一个reducer
function reducer (state, action) {
//初始化state 和 switch case 计算返回新state
}

//生成store
const store = createStore(reducer)

//监听数据变化重新渲染页面
store.subscribe(() => renderApp(store.getState()))

//后面可以随意dispatch了,页面自动更新
store.dispatch(......)

完整代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
function createStore( stateChanger) {
let state = null
const listeners = []
const subscribe = (listener) => listeners.push(listener)
const getState = () => state
const dispatch = (action) => {
state = stateChanger(state, action) // 覆盖原对象
listeners.forEach((listener) => listener())
}
dispatch({}) // 初始化 state
return { getState, dispatch, subscribe}
}

function renderApp(newAppState, oldAppState = {}) {
if (newAppState === oldAppState) return // 数据没有变化就不渲染了
console.log('render app...')
renderTitle(newAppState.title, oldAppState.title)
renderContent(newAppState.content, oldAppState.content)
}

function renderTitle(newTitle, oldTitle = {}) {
console.log('render title...')
if (newTitle === oldTitle) return // 数据没有变化就不渲染了
const titleDOM = document.getElementById('title')
titleDOM.innerHTML = newTitle.text
titleDOM.style.color = newTitle.color
}

function renderContent(newContent, oldContent = {}) {
if (newContent === oldContent) return // 数据没有变化就不渲染了
console.log('render content...')
const contentDOM = document.getElementById('content')
contentDOM.innerHTML = newContent.text
contentDOM.style.color = newContent.color
}
function stateChanger (state, action) {
if (!state) {
return {
title: {
text: 'React.js 小书',
color: 'red',
},
content: {
text: 'React.js 小书内容',
color: 'blue'
}
}

}
switch (action.type) {
case 'UPDATE_TITLE_TEXT':
return {
...state,
title: {
...state.title,
text: action.text
}
}
case 'UPDATE_TITLE_COLOR':
return {
...state,
title: {
...state.title,
color: action.color
}
}
default:
return state
}
}

const store = createStore( stateChanger)

let oldState = store.getState() // 缓存旧的 state

store.subscribe(() => {
const newState = store.getState() // 数据可能变化,获取新的 state
renderApp(newState, oldState) // 把新旧的 state 传进去渲染
oldState = newState // 渲染完以后,新的 newState 变成了旧的 oldState,等待下一次数据变化重新渲染
})

renderApp(store.getState()) // 首次渲染页面

store.dispatch({ type: 'UPDATE_TITLE_TEXT',text: '《React.js 小书》'}) // 修改标题文本
store.dispatch({ type: 'UPDATE_TITLE_COLOR',color: 'blue'}) // 修改标题颜色

React-redux

1
2
3
4
5
6
const mapStateToProps = (state) =>{
return {
themeColor:state.themeColor
}
}
Header = connect(mapStateToProps)(Header)

总结过程