概述
redux是一个基于JavaScript状态容器,他可以进行全局状态管理。与(Vuex类似)。
随着JavaScript单页面开发日益复杂,Javascript需要管理更多的state状态,这些state可能包括服务器响应,数据缓存,本地生成未持久化到服务器的数据,也包括ui状态等等。
管理不断变化的state非常麻烦,如果一个model的变化需要引起另外的model的变化,那么当View发生变化时,就可能引起对应的model以及另一个model的变化,依次引起其他的View的变化,所哟逻辑处理会比较混乱,用Redux就是为了解决这个问题的。Redux可以进行全局状态管理。
redux组成
state
一个应用会有许多state或者说有各种状态,整个应用的state都被保存在一个object tree中,object只存在唯一的一个store。
action
修改state需要action来触发,这样确保了(View)视图和网络请求不能直接修改state。他们只能表达想要修改的意图,所有的修改都会被集中化处理。一个一个的执行。
reducers
为了描述action如何改变state,需要reducers。
reducers先接收以前的state和action,并返回新的state给store。
store
store就是把action与reducer联系到一起的对象。他维持应用state状态,他提供getState()方法获取state,提供dispath()方法发送action。
工作流程:
我需要在React 组建中改变状态
1.就需要让Action创建一个action对象
2.然后再调用store.dispath(action对象)。
3.store就会将(previousState,action)传递给reducers,reducers处理完成后,就会返回NewState。
4.store再将新的state更新给React组建。
开发环境
1 2 3
| npm install redux
npm install react-redux
|
案例1
目录结构
1 2 3 4 5 6 7
| store ├─ actions │ └─ user.js ├─ index.js └─ reducers ├─ index.js └─ user.js
|
创建store
1 2 3 4 5 6 7 8 9 10
|
import {createStore} from "redux"; import Reducers from "./reducers" const store = createStore(Reducers); export default store;
|
创建actions
1 2 3 4 5 6 7 8 9 10 11 12
|
export const Set_Token = token => { return { type: 'Set_Token', token } }
|
创建reducers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
const userReducer = (state = {token: null}, action) => { switch (action.type) { case 'Set_Token': let newState = {...state}; newState.token = action.token; state.token=action.token; return newState; default: return state } }
export default userReducer
|
1 2 3 4 5 6 7 8
| import {combineReducers} from 'redux' import userReducer from './user'
const Reducers = combineReducers({ userReducer }) export default Reducers
|
在组件中使用
获取state
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import store from '../store/index' import React, {Component} from "react" import {View,Text} from "react-native";
class getState extends Component{ constructor() { super(); this.state= { token: store.getState().userReducer.token } } render() { return ( <View><Text>{this.state.token}</Text></View> ) } } export default getState;
|
改变state
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import store from '../store/index' import React, {Component} from "react" import {Button} from "react-native"; import {Set_Token} from "./actions/user"; class setState extends Component{ constructor() { super(); } changeToken=(token)=>{ const action=Set_Token(token) store.dispatch(action) } render() { return ( <Button title="设置Token" onPress={()=>{this.changeToken("123")}} /> ) } } export default setState;
|
第三方库redux-thunk
因为原生的redux只能处理同步的state,有些功能需要异步处理,比如登陆功能,用户发送登陆请求后,服务器会返回token,此时我们需要把token保存在state里面,而发送登陆请求(网络请求)是异步的,此时我们就需要用redux-thunk来异步更改state。
安装redux-thunk
下面这个案例集成了redux-thunk
一个简单的登陆案例
目录结构
1 2 3 4 5 6 7
| store ├─ actions │ └─ user.js ├─ index.js └─ reducers ├─ index.js └─ user.js
|
创建store
1 2 3 4 5 6 7 8 9 10 11 12 13
|
import {createStore, applyMiddleware} from "redux";
import thunk from "redux-thunk"; import Reducers from "./reducers" const store = createStore(Reducers, applyMiddleware(thunk)); export default store;
|
创建actions
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
|
import {login} from '../../api/user'
export const Set_Token = token => { return { type: 'Set_Token', token } }
export const LoginAction=(userInfo)=>{ const {username,password}=userInfo; return dispatch => { login({ username: username.trim(), password: password }).then(response => { const { data } = response const action = Set_Token(data.token) dispatch(action); }).catch(error => { }) } }
|
创建reducers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
const userReducer = (state = {token: null}, action) => { switch (action.type) { case 'Set_Token': let newState = {...state}; newState.token = action.token; state.token=action.token; return newState; default: return state } }
export default userReducer
|
1 2 3 4 5 6 7 8
| import {combineReducers} from 'redux' import userReducer from './user'
const Reducers = combineReducers({ userReducer }) export default Reducers
|
在组件中调用异步函数
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
| import store from '../store/index' import React, {Component} from "react" import {Button} from "react-native"; import {LoginAction} from "./actions/user"; class setState extends Component{ constructor() { super(); } changeToken=()=>{ let user={ username:"admin", password:"admin" } const action=LoginAction(user) store.dispatch(action) } render() { return ( <Button title="登陆" onPress={()=>{this.changeToken}} /> ) } } export default setState;
|
结语
如有错处,望指正。
时间:2022.05.13