React-Redux
知识点
-
redux redux-thunk
-
redux redux-saga
-
mobx
简介
redux是什么?
Redux是js应用的 一种可预测的状态容器(状态管理工具)
为什么要使用redux?
因为react只是DOM的抽象层,它没有涉及到另外两个方面 ,不是一个完整的web应用解决方案
1. 代码结构
2. 组件之间的通信
redux出现的时间?
1. 2015年
2. 它是2013年出现的flux的升级版
3. redux将flux和函数式编程结合在一起了
redux什么时候使用?
1. 当你做这个项目的时候你就知道了
2. 前后端数据交互多、前端表单也很多
3. redux并不是必须使用的
核心概念
Redux的构成部分
-
store
用于存储state 管理state的地方
-
actionCreators
动作的创建者,用于创建action, 用于区别界面到底做了哪些动作
-
reducers
用于修改数据 reducers必须是纯函数
-
View
界面,在react中,其实就是组件
Redux的设计思想:
1. Web 应用是一个状态机,视图与状态是一一对应的。
2. 所有的状态,保存在一个对象里面(唯一数据源)
1. Redux的数据是一个对象
Redux三大使用原则
1. 单一数据源(Single Source of Truth)
2. 状态是只读的(返回值必须是新对象,不能直接修改原state) State is read-only
3. 使用纯函数来执行修改数据(输入输出一致)
Redux的流程(Flow)
-
打造store
-
打造reducers给store初始值
-
将store中数据取出来给了组件
-
组件中触发动作激活actionCreators
1.比如一个点击事件
2.比如一个输入事件
3.一个前后端交互
-
actionCreators 创建action 发送reducers
-
reducers中修改数据
流程图
Redux 插件
-
redux
redux核心库
$ yarn add redux
-
redux-thunk
用于实现异步数据请求的redux中间件
$ yarn add redux-thunk
-
redux-saga
用于实现异步数据请求的redux中间件
$ yarn add redux-saga
-
react-redux
用于实现redux的数据划分:例如 home/user/list…
$ yarn add react-redux
-
redux-devtools-extension
用于激活chrome浏览器的redux调试插件
$ yarn add redux-devtools-extension
-
Redux-DevTools 浏览器调试工具
浏览器插件:Redux-DevTools
下载地址:https://chrome.zzzmh.cn/info?token=lmhkpmbekcpmknklioeibfkpmmfibljd
Redux-thunk 版本使用
1.打造store
src/stroe/index.ts 或者 src/models/index.ts
const store=createStore(reducer,enhancer)
reducer 为修改数据的纯函数,为rootReducer(整个项目)
rootReducer为整个项目的集中管理者,下有很多reducers
enhancer 中间件(中间件就是具有特定功能的封装函数)
applyMiddleware 为中间件的执行函数
底层原理:函数柯里化
import thunk from “redux-thunk”;
import { composeWithDevTools } from “redux-devtools-composeWithDevTools”;
import { createStore,applyMiddleware } from 'redux'; import rootReducer from './rootReducer'; import thunk from 'redux-thunk' // todo 用于实现异步数据请求 import { composeWithDevTools } from 'redux-devtools-extension' const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk))) export default store ;
2.打造rootReducer
src/store/rootReducer.ts
//todo 打造rootReducer import { combineReducers } from 'redux' const rootReducer = combineReducers({ // 其他划分的reducer count / todo / list }) export default rootReducer
3.通过跨组件通信来进行数据通信(store数据给组件)
src/index.tsx
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; import "antd/dist/antd.css"; import { // HashRouter,//todo 表示选择hash模式 BrowserRouter, // todo 表示选择history模式 } from "react-router-dom"; //add 导入store和跨组件通信组件 import store from "./store"; import { Provider } from "react-redux"; ReactDOM.render( <React.StrictMode> <BrowserRouter> {/* add 使用Provider组件包裹App组件*/} <Provider store={store}> <App /> </Provider> </BrowserRouter> </React.StrictMode>, document.getElementById("root") );
4.打造计数案例的count reducers
src/reducer/count.ts
reducer必须是一个纯函数(注意输入和输出保持一致)
输入 给参数previousState时state必须在对象{}中,这叫唯一数据源
输出 return必须是对象,redux的state是只读的,不能直接操作previousState,需要进行拷贝
拷贝方式
//浅拷贝 --只能拷贝一层 const state=Object.create(previousState) const state=Object.assign({ },previousState) const state={ ...previousState} const state=_.clone(previousState) //使用lodash
//深拷贝 --可以拷贝多层 // 使用lodash方式 const state=_.cloneDeep(previousState) // immutable.js方式 import { Map} from 'immutable' const initState=Map({ n:1}) const state=previousState // json序列化方式 const state=JSON.parse(JSON.stringify(previousState))
const initState={ n:1 } const countRdeucer=(previousState=initState,action={ }) => { // previousState就是先前的state // action就是actionCreator发过来的action return { ...previousState}; } export default countRdeucer
5.在rootReducer中导入使用countReducer
src/store/rootReducer.ts
使用格式: 区块名称:导入的区块
import { combineReducers } from "redux"; import count from "../reducer/count"; const rootReducer =combineReducers({ // 内容为其他划分的reducers count:count }) export default rootReducer
6.用connect高阶组件从store中将数据取出给到组件
高阶组件
1.高阶组件就是一个函数,接收一个组件作为参数,返回一个新组件
2.功能:复用逻辑
connect函数是一个高阶组件
- 使用了connect,该组件就会用于store的数据和方法
- connect(arg1,arg2)(组件)
1.arg1是一个callback,用于获取store中的数据,然后以props形式给该组件
2.arg2是一个callback, 用于获取actionCretaor中的方法,然后以props形式给该组件
- 作用就是将store中的数据,actionCreators中的方法,以props属性的形式给到该组件,该组件就不需要定义数据和方法
bindActionCreators函数用于绑定action
//src /pages/Await.tsx import React, { ReactElement, useState } from "react"; import { FC } from "react"; import countAction from "../../actions/count"; // 绑定action的 import { bindActionCreators } from "redux"; import { connect } from "react-redux"; interface Props { n:number; increment:(val:string)=>any; decrement:(val:string)=>any; } interface IcountState {n: number} const Await: FC<Props> = ({n,increment,decrement}) => { const [val,setVal]=useState<string>('') const getVal=(e:any)=>{setVal(e.target.value)} return <div> {/* 受控组件 */} <input type="text" placeholder="请输入操作的数据" value={val} onChange={getVal}/> <button onClick={()=>{increment(val)}}> + </button> <button onClick={()=>{decrement(val)}}> - </button> <p>{n}</p> </div>; }; export default connect( ({count}:{count:IcountState}) => { return count }, (dispatch) => { return bindActionCreators(countAction,dispatch) } )(Await);
8.打造公共常量
src/constant/index.ts
// todo count的相关常量 export const INCREMENT = 'increment' export const DECREMENT = 'decrement'
9.打造actionCreator
src/actions/count.ts
打造属于count的actionCreators:
action的作用
创建action
通过return 发送action至对应的reducer
import * as type from './../constant/index'; // todo 打造属于count的actionCreators // !! 没有异步数据请求时这样写 const countAction={ increment(val:string){ // count 递增方法 const action={ type:type.INCREMENT, payload:val } return action }, decrement(val:string){ // count 递减方法 const action={ type:type.DECREMENT, payload:val } return action } } export default countAction
10.reducer中的操作数据(修改逻辑)
src/reducer/count
逻辑:接收action发送过来的type,进行与常量的匹配,然后执行对应修改state的操作,并返回给store中的数据,store在将数据给组件
import * as constant from '../constant' interface IAction { type: string;payload: string;} const initState = { n: 1} const countReducer = (previousState = initState,{ type, payload }: IAction) => { switch ( type ) { case constant.INCREMENT: // 递增 return { ...previousState,n: previousState.n + Number(payload)} case constant.DECREMENT: // 递减 return { ...previousState,n: previousState.n - Number(payload)} default: return { ...previousState} } } export default countReducer
今天的文章Redux(Redux-thunk)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/65427.html