网上广为流传的Redux流程图
我的个人理解:
- store: 仓库, 用于保存状态及操作状态相关的动作
- state: 状态,数据
- action: 是一个对象,用来描述发生了什么。通常这个对象中有两个属性:type,payload,type表示具体的action类型,payload是进行状态更新时携带的数据(有效载荷)
- reducer:是一个函数,用于更新状态。该函数接受两个参数:state、action,state表示待更新的旧状态,action表示如何更新状态。reducer()是唯一能够更新状态的地方。renducer()函数是一个纯函数,在reducer()内部返回更新后的新的状态值(不会直接更新旧的状态数据)
- dispatch: 触发 reducer()的调用。不要直接调用 reducer()函数更新状态,应该在组件中使用dispath()方法来触发reducer()的调用。dispatch 方法会接受action 参数
流程我的理解是: 在组件中通过dispatch 触发Action,在index.js中通过携带store中的旧state与action 流向reducer reducer处理完数据后,返回新的state.并更新界面
使用步骤
- 创建 reducer 函数
会建立一个 reducers
的目录,在 reducers
目录中保存各独立的 reducer 函数,然后提供 index.js 将各独立 reducer 合并为一个根 reducer:
// user.js
// 初始状态
const initialState = {
username: '',
token: ''
}
// reducer() 函数
export default (state = initialState, { type, payload }) => {
switch (type) {
case 'LOGIN_SUCCESS':
return { ...state, ...payload }
default:
return state
}
}
// todos.js
// 初始状态
const initialState = []
// reducer() 函数
export default (state = initialState, { type, payload }) => {
switch (type) {
case 'ADD':
return [payload, ...state]
default:
return state
}
}
// index.js:多个独立 reducer 合并为一个根 reducer
import { combineReducers } from 'redux'
import todosReducer from './todos'
import userReducer from './user'
// 将多个独立的 reducer 合并为一个根 reducer
export default combineReducers({
todos: todosReducer,
user: userReducer
})
- 创建 store
会建立一个 store 目录,在 store 目录中提供 index.js 来导出创建好的 Store 对象:
import { createStore } from 'redux'
import rootReducer from '../reducers'
// 创建 store
export default createStore(rootReducer)
- 创建 action creator 函数
建立 actions
目录,在目录的文件中添加 action creator 函数,用于生成各动作对应的 action 对象:
// 添加待办事项的 action 对象
export const addTodoItemAction = title => {
return {
type: 'ADD',
payload: {
id: Math.random(),
title,
completed: false
}
}
}
- 在
./src/index.js
入口文件中保存 store:
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { Provider } from 'react-redux'
import store from './store'
// 在浏览器中渲染 DOM 节点
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
- 调用到
react-redux
绑定库中的 connect() 方法,在组件中连接 redux 的 store:
import React, { Component } from 'react'
import { connect } from 'react-redux'
import TodoItem from './TodoItem'
class TodoList extends Component {
render() {
return (
<div>
列表
{
this.props.todos.map(todo => {
return (
<TodoItem key={todo.id} {...todo} />
)
})
}
</div>
)
}
}
// 将返回对象中的属性映射到组件的 props 中
const mapStateToProps = state => ({
todos: state.todos
})
const mapDispatchToProps = dispatch => ({
toggle: id => dispatch(toggleTodoItemAction(id)),
remove: id => dispatch(removeTodoItemAction(id))
})
// connect() 调用之后,返回的是一个高阶组件
const hoc = connect(mapStateToProps, mapDispatchToProps)
export default hoc(TodoList)
最后可以实现一个最简单的todolist