1. Redux
1.1 store
Store 就是把它们联系到一起的对象。Store 有以下职责:
- 维持应用的 state;
- 获取:getState() 方法获取当前的 state 树。
- 更新:dispatch(action) 方法更新 state。这是触发 state 变化的惟一途径;
- 监听:subscribe(listener) 注册监听器,返回的函数注销监听器。
import { createStore } from 'redux';
const store = createStore(reducer);
1.2 Reducer 函数
Reducers 指定了应用状态的变化如何响应 actions 并发送到 store。reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
const reducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
1.3 Action 函数
Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源,通过 store.dispatch() 将 action 传到 store。
{ type: 'INCREMENT' }
1.4 Example
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import Counter from './components/Counter'
import counter from './reducers'
const store = createStore(counter)
ReactDOM.render(
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
/>,
document.getElementById('root')
)
store.subscribe(render)
Counter.js
import React, { Component } from 'react'
class Counter extends Component {
constructor(props) {
super(props)
}
incrementIfOdd = () => {
if (this.props.value % 2 !== 0) {
this.props.onIncrement()
}
}
incrementAsync = () => {
setTimeout(this.props.onIncrement, 1000)
}
render() {
const { value, onIncrement, onDecrement } = this.props
return (
<>
Clicked: {value} times
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
<button onClick={this.incrementIfOdd}>Increment if odd</button>
<button onClick={this.incrementAsync}>Increment async</button>
</>
)
}
}
export default Counter
reducers/index.js
export default (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
2. React-Redux
2.1 Provider 标签
<Provider store>
使所有层级中的 connect() 方法都能够获得 Redux store。
<Provider store={store}>
<App />
</Provider>
2.2 connect 函数
连接 React 组件与 Redux store,返回一个新的已与 Redux store 连接的组件类。
connect([mapStateToProps], [mapDispatchToProps])(App)
- mapStateToProps
负责输入逻辑,将state映射到 UI 组件的参数
- mapDispatchToProps
负责输出逻辑,将用户对 UI 组件的操作映射成 Action。
2.3 Example
index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider, connect } from 'react-redux'
import Counter from './components/Counter'
import counter from './reducers'
const store = createStore(counter)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Counter.js
import React, { Component } from 'react'
// 把 Redux 中的 value 拿过来用,渲染的时候就可以直接使用 this.props.value
function mapStateToProps(state) {
return {
value: state.count
}
}
// 把 dispatch 也变成了可以直接使用 this.props.onIncreaseClick
function mapDispatchToProps(dispatch) {
return {
onIncreaseClick: () => dispatch({ type: 'increase' })
}
}
class Counter extends Component {
render() {
const { value, onIncreaseClick } = this.props
return (
<div>
<span>{value}</span>
<button onClick={onIncreaseClick}>Increase</button>
</div>
)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
reducers/index.js
export default = (state = { count: 0 }, action) => {
const count = state.count
switch (action.type) {
case 'increase':
return { count: count + 1 }
default:
return state
}
}