Redux
安装
# NPM
npm install redux
# Yarn
yarn add redux
state
- state就是存放数据的地方
- state数据需要通过
reducer 来管理 - 发起reducer需要通过
dispatch - dispatch的参数是一个
action 总结来说,state 的修改需要通过dispatch 发起一个action ,然后通过reducers 返回一个新的state。
Action
- action是把数据从应用传到store的有效载荷,是store数据的唯一来源。
- 需要通过
store.dispatch() 将action 传到store - 格式中type是固定的字段,其他字段可以自定义
const ADD_TODO = 'ADD_TODO';
function addTodo(payload) {
return {
type: ADD_TODO,
payload,
}
}
dispatch(addTodo(0))
Reducer
Reducers?指定了应用状态的变化如何响应?actions?并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新state。
设计state结构
- 在 Redux 应用中,所有的 state 都被保存在一个单一对象中。
Action 处理
- 需要通过type区分出来需要如何修改数据,调用不同的方法
- 修改state的数据,只能返回新的state,不可以直接修改state的数据
- reducers接受两个参数,一个是state, 一个是action返回的对象
const ADD_TODO = 'ADD_TODO';
const initialState = {
todos: []
}
function todos(state = [], action) {
switch (action.type) {
case ADD_TODO:
return [
...state,
...action.payload
]
default:
return state
}
return state;
}
function todoApp(state, action) {
return {
todos: todos(state.todos, action)
}
}
模块化reducers
在过多的reducers中,可以通过不同的模块进行拆分,然后通过combineReducers 将拆分的合并起来。
combineReducers() ?所做的只是生成一个函数,这个函数来调用你的一系列 reducer,每个 reducer?根据它们的 key 来筛选出 state 中的一部分数据并处理,然后这个生成的函数再将所有 reducer 的结果合并成一个大的对象。
import { combineReducers } from 'redux'
const todoApp = combineReducers({
todos,
})
function todoApp(state, action) {
return {
todos: todos(state.todos, action)
}
}
export default todoApp
命名空间问题
由于redux并没有采用命名空间这种方式来区分模块,模块在进行diapatch时是对根store抛发的,所以他会触发所有的子reducer,因此各个模块之间要明确好type的格式
Store
创建state
import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)
发起Action,更新数据
import { addTodo } from './actions'
store.dispatch(addTodo('learn about actions'))
react-redux
安装
npm install --save react-redux
传入Store
- 通过
Provider 容器讲store传入组件中 - 最好是讲该容器组件放到根组件中
import React from 'react'
import { Provider } from 'react-redux'
import store from './store/index'
import App from './compontns/App'
render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
)
组件中使用state数据
- 通过
connect 将state和dispatch等方法注入到组件里面 - connect有两个参数
mapStateToProps 、mapDispatchToProps mapStateToProps 是一个函数,接受state 作为参数,返回一个对象mapDispatchToProps 是函数时:有两个参数,一个是disaptch 用来调用action更新store数据,另一个是当前组件的props mapDispatchToProps 是对象时:键值应该是一个函数,被当做action ,回自动发出该action
import { connect } from 'react-redux'
const mapStateToProps = state => {
return {
todos: state.todos
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch({
type: ADD_TODO,
payload: ownProps.todos
})
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Home)
redux-saga
安装
npm install redux-sage
yarn add redux-saga
简介
- redux-saga是一个用于管理redux应用一部操作的中间件
- redux-saga是通过generator函数创建的
配置
import {createSrote, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducers from './reducers';
import rootSaga from './saga'
const sageMiddleware = createSagaMiddleware();
let store = createStore(reducers, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(rootSaga);
export default store;
saga方法书写
import { call, put, takeEvery } from 'redux-saga/effects'
const getData = () => {
const products = yield call(Api.fetch, '/products')
yield put({
type: ADD_TODO,
payload: products
})
}
function *stateSaga() {
yield takeEvery(ADD_TODO, getData)
yield takeEvery(ADD_TO, getInfo)
}
export const stateSaga = () => {
}
总结
react-redux 是在action发起后监听到需要进行处理的则进行处理,是个在action 后面和reducer 前面的那一步骤的takeEvery 允许多个getData实例同时启动- 如果要拦截多个action,可以使用多个
takeEvery ,不用考虑先后顺序,这个是可以同时触发的。
|