1.redux的使用
-
去除count自身的状态
-
src下建立:
-
-src
-reduc
-store.js
-count_reducer.js
目录结构:
-
-
Store.js
-
引入redux中的createState函数,
-
创建一个storecreateState调用是传入一个为其服务的reducer,
-
记得暴露stoer对象
代码:
/** * 该文件专门用于暴露一个store对象,整个应用只有一个store对象 */ // 引入createStore 专门用于创建redux中最为核心的store对象 import { createStore } from "redux"; // 引入为count组件服务的reducer import countReducer from './count_reducer' // 暴露store export default createStore(countReducer);
-
-
Count_reducer.js
-
reducer的本质是一个函数,接收preState,action,返回处理后的状态
-
reducer的两个作用:初始化数据,处理数据
-
reducer被第一次调用时,时store自动触发的,传递的preState时dudefined
代码:
/** * 初始化状态 * 加工状态 * * * 1.该文件就是用于创建一个为count服务的reducer,reducer的本质就是一个函数 * 2.reducer接收两个参数,分别为:之前的状态(preState),动作对象(action) */ export default function countReducer(preState = 100, action) { let { type, data } = action; switch (type) { case "increment": //处理加 return preState + data; case "decrement": //处理减 return preState - data; default: //不处理的话直接返回初始化数据 return preState; } }
-
-
在index.js中检测store状态的改变,一旦发生改变重新渲染
备注:redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠自己写
在
index.js文件里面加入下列代码import store from './redux/store' store.subscribe(() => { ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById("root") ); //只要redux数据更新 就会触发render的更新 });求和案例redux完整版本
新增文件
-
count_action.js专门用于创建action对象/** * 该文件专门为count组件生成action对象 */ import { INCREMENT, DECREMENT } from "./constant"; // 加法 const createIncrementAction = (data) => ({ type: INCREMENT, data }); //返回一个对象 // 减法 const createDecrementAction = (data) => ({ type: DECREMENT, data }); export { createIncrementAction, createDecrementAction }; -
constant.js放置容易写错的type/** * 该模块是用于定义action对象中type类型的常量值,目的:便于管理的同时防止程序员写错单词 */ export const INCREMENT = "increment"; export const DECREMENT = "decrement";
求和案例redux异步action版
-
明确:延迟的动作不想交给组件自身,想交给action
-
何时需要异步action:要想对状态进行操作,但是具体的数据靠异步任务返回
-
具体编码:
-
yarn add redux-thunk ,并配置在store中
-
创建action的函数不再返回一般对象,而是一个函数,该函数中写异步任务
-
异步任务有结果后,分发一个同步的action去真正操作数据
//异步执行,就是指action返回的值为函数,异步action中一般都会调用同步action,非必须使用 const createIncrementAsyncAction = (data, time) => { return (dispath) => { setTimeout(() => { dispath(createIncrementAction(data)); //在异步方法里面调用同步方法 }, time); }; };
-
-
备注:异步action不是必须要写的,完全可以自己等待异步任务的结果了再去分发同步action
求和案例react-redux的基本使用
-
明确两个概念
- UI组件:不能使用任何redux的api,只负责页面的呈现,交互等
- 容器组件:负责和redux通行,将结果交给组件
-
如何创建一个容器----靠react-redux的
connect函数-
connect(mapStateToProps, mapDispatchToProps)(UI组件); -
mapStateToProps:映射状态,返回值是一个对象 -
mapDispatchToProps:映射操作状态的方法,返回值是一个对象容器页面代码展示:
// 引入ui组件 import AddRedux from "../../view/AddRedux"; //引入connect用于链接ui组件和redux import { connect } from "react-redux"; //引入action import { createIncrementAction, createIncrementAsyncAction, createDecrementAction, } from "../../redux/count_action"; /** * mapStateToProps返回的是一个对象 * 1.返回的对象中的key就作为传递给ui组件props的key * 2.value就作为传递给ui组件props的value * 3.mapStateToProps用于传递状态 * * @param {*} state * @returns */ const mapStateToProps = (state) => { return { count: state }; }; /** * * * mapDispatchToProps返回的是一个对象 * 1.返回的对象中的key就作为传递给ui组件props的key * 2.value就作为传递给ui组件props的value * 3.mapDispatchToProps用于操作状态的方法 * @param {*} dispatch * @returns */ const mapDispatchToProps = (dispatch) => { return { add: (data) => dispatch(createIncrementAction(data)), //通知redux执行加法 sub: (data) => dispatch(createDecrementAction(data)), addAsync: (data) => dispatch(createIncrementAsyncAction(data, 1000)), }; }; // 使用connect()()创建并暴露一个Count的容器组件 export default connect(mapStateToProps, mapDispatchToProps)(AddRedux);mapStateToProps和mapDispatchToProps的简化写法 (mapDispatchToProps也可以是一个对象)export default connect( (state) => ({ count: state }), //简写方法 { //简化写法 react-redux内置api自动分发dispatch add: createIncrementAction, //通知redux执行加法 sub: createDecrementAction, addAsync: createIncrementAsyncAction, } )(AddRedux);
-
-
备注:容器组件中的store是靠props传进去的,而不是容器组件中直接引入
使用容器页面直接引入容器组件和store文件
import Count from "./containers/Count"; import store from "./redux/store"; <div className="App"> {/* 给容器组件传递store */} <Count store={store} /> </div>求和案例react-redux优化
-
容器组件和UI组件整合一个文件
-
无需自己给容器组件传递store,给包裹一个Provider
<Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider>, -
使用react-redux不需要再监测redux更新状态,react-redux可以自动监测更新页面
-
mapDispatchToProps可以写成对象
-
一个组件要和redux “打交道”要经过那几个步骤
- 定义ui组件
- 引入connect生成一个容器组件,并暴露
- 在ui组件中通过this.props.xxxx读取和操作状态
-
容器组件和ui组件整合
import React, { Component } from "react"; import { Button, Select } from "antd"; //引入connect用于链接ui组件和redux import { connect } from "react-redux"; //引入action import { createIncrementAction, createIncrementAsyncAction, createDecrementAction, } from "../../redux/count_action"; const { Option } = Select; class AddRedux extends Component { state = { initVal: 0, selectArr: [1, 2, 3, 4, 5, 6, 7], selectVal: 1, }; // 加 increment = () => { let { selectVal } = this.state; this.props.add(selectVal); }; sub = () => { let { selectVal } = this.state; this.props.sub(selectVal); }; mul = () => { let { selectVal } = this.state; let { count } = this.props; if (count % 2 != 0) { this.props.add(selectVal); } }; division = () => { let { selectVal } = this.state; this.props.addAsync(selectVal,1000); }; selectChange = (val) => { console.log(val); this.setState({ selectVal: val, }); }; render() { console.log(this.props, "react-redux"); let { initVal, selectArr, selectVal } = this.state; return ( <div style={{ margin: "20px" }}> <h1>初始值:{this.props.count}</h1> <Select value={selectVal} style={{ width: "32%", margin: "10px" }} onChange={this.selectChange} > {selectArr.map((item) => { return ( <Option value={item} key={item}> {item} </Option> ); })} </Select> <br /> <Button type="primary" style={{ margin: "0 10px" }} onClick={() => this.increment()} > + </Button> <Button type="primary" style={{ margin: "0 10px" }} onClick={() => this.sub()} > - </Button> <Button type="primary" style={{ margin: "0 10px" }} onClick={() => this.mul()} > 当前就和为奇数再加 </Button> <Button type="primary" style={{ margin: "0 10px" }} onClick={() => this.division()} > 异步加 </Button> </div> ); } } export default connect( (state) => ({ count: state }), //简写方法 { //简化写法 react-redux内置api自动分发dispatch add: createIncrementAction, //通知redux执行加法 sub: createDecrementAction, addAsync: createIncrementAsyncAction, } )(AddRedux);
-
-