1、什么是Redux
学习文档
什么是Redux
redux
是一个专门用于做状态管理
的JS
库(不是react
插件库)- 它可以用在
react, angular, vue
等项目中, 但基本与react
配合使用 作用
:集中式管理React
应用中多个组件共享的状态
什么情况下需要使用redux
- 某个组件的状态,需要让其他组件可以随时拿到(共享)
- 一个组件需要改变另一个组件的状态(通信)
总体原则
:能不用就不用, 如果不用比较吃力才考虑使用
redux工作流程
Reducers
:可以初始化状态(一次),也可以加工状态(多次)
2、redux的三个核心概念
action
- 标识要执行行为的对象(动作的对象)
- 包含2个属性
type
: 标识属性,值为字符串,唯一,必要属性data
:数据属性,值类型任意,可选属性
eg: const action = { type: 'INCREMENT', data: 2 }
reducer
- 用于初始化状态、加工状态
- 加工时,根据旧的
state
和action
,产生新的state
的纯函数
注意:返回一个新的状态,不要修改原来的状态
store
- 将
state、action、reducer
联系在一起的对象 - 那么如何得到此对象?
import {createStore} from 'redux'
import reducer from './reducers'
const store = createStore(reducer)
- 这个对象的功能又是什么呢?
getState()
:得到state
dispatch(action)
:分发action
,触发reducer
调用,产生新的state
subscribe(listener)
: 注册监听, 当产生了新的state
时, 自动调用
3、redux的核心API
createStore()
作用:创建包含指定reducer
的对象
格式:
import {createStore} from 'redux'
import counter from './reducers/counter'
const store = createStore(counter)
store对象
作用:redux
库最核心的管理对象,它的内部维护着:state,reducer
核心方法:getState(),dispatch(action),subscribe(listener)
格式:
store.getState()
store.dispatch({type:'INCREMENT', number})
store.subscribe(render)
applyMiddleware()
作用:应用上基于redux
的中间件(插件库)
格式:
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk' // redux异步中间件
const store = createStore(
counter,
applyMiddleware(thunk) // 应用上异步中间件
)
combineReducers()
作用:合并多个reducer
函数
格式:
export default combineReducers({
user,
chatUser,
chat
})
4、react-reudx
一个react
插件库,专门用来简化react
应用中使用redux
这里将组件分为两大类:UI
组件,容器组件
UI
组件
- 只负责
UI
的呈现,不带有任何的业务逻辑 - 通过
props
接受数据(一般数据和函数) - 不使用任何
redux
的API - 一般保存在
components
文件夹中
容器组件
- 负责管理数据和业务逻辑,不负责
UI
呈现 - 使用
redux
的API
- 一般保存在
containers
文件夹下
相关API:
Provider、connect()、mapStateToprops()、mapDispatchToProps()
Provider
让所有的组件可以得到state
数据
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app'),
);
connect()
==> 由React-Redux
提供
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])(MyComponent)
connect
的作用:用于从 UI
组件生成容器组件。是连接React
组件和Redux store
建立组件与store.state
和dispatch
的映射关系。连接操作不会改变原来的组件类。
eg:
import { connect } from 'react-redux'
const VisibleTodoList = connect()(TodoList);
TodoList
是UI
组件,VisibleTodoList
就是由React-Redux
通过connect
方法自动生成的容器组件
但是,因为没有定义业务逻辑,上面的这个容器组件毫无意义,只是UI
组件的一个单纯的包装层。为了定义业务逻辑,需要给出下面两方面的信息。
- 输入逻辑:外部的数据(即
state
),如何转换为UI
组件的参数- 输出逻辑:用户发出的动作如何变为Action对象,从UI组件传出去
connect
方法的完整API
import { connect } from 'react-redux'
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
API
分析:connect
方法接受两个参数:mapStateToProps
和mapDispatchToProps
。他们定义了UI
组件的业务逻辑。前者负责输入逻辑(负责将state映射到UI组件的参数props),后者负责输出逻辑(负责将用户对UI组件的操作映射成Action)
mapStateToprops()
mapStateToProps
是一个函数,建立一个从(外部的)state对象到(UI组件的)props对象的映射关系
const mapStateToprops = function (state) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
解析:mapStateToProps
是一个函数,它接受state
作为参数,返回一个对象。这个对象有一个todos
属性,代表UI
组件的同名参数,后面的getVisibleTodos
也是一个函数,可以从state
中算出todos
的值
那么是如何计算的呢?
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'SHOW_ALL':
return todos
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed)
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed)
default:
throw new Error('Unknown filter: ' + filter)
}
}
mapStateToProps
会订阅 Store
,每当state
更新的时候,就会自动执行,重新计算UI
组件的参数,从而触发 UI
组件重新渲染。
mapDispatchToProps()
mapDispatchToProps
是connect函数的第二个参数,用于建立UI
组件和store.dispatch
的映射关系mapDispatchToProps
可以是对象或函数
简洁语法可以直接指定为actions
对象或包含多个action
方法