旅游网页设计模板网站,邵阳网站开发公司推荐,长春制作网站软件,厦门网站建设、React#xff08;react18#xff09;中组件通信04——redux入门 1. 前言1.1 React中组件通信的其他方式1.2 介绍redux1.2.1 参考官网1.2.2 redux原理图1.2.3 redux基础介绍1.2.3.1 action1.2.3.2 store1.2.3.3 reducer 1.3 安装redux 2. redux入门例子3. redux入门例子——优… Reactreact18中组件通信04——redux入门 1. 前言1.1 React中组件通信的其他方式1.2 介绍redux1.2.1 参考官网1.2.2 redux原理图1.2.3 redux基础介绍1.2.3.1 action1.2.3.2 store1.2.3.3 reducer 1.3 安装redux 2. redux入门例子3. redux入门例子——优化1reducer 和 store拆开3.1 想要实现的效果3.2 代码设计3.3 添加 重新渲染3.4 附代码 4. redux入门例子——优化2拆出action4.1 关于action的其他说明4.2 优化——拆出action4.3 优化——动态加减数字4.3.1 优化看效果4.3.2 附代码 1. 前言
1.1 React中组件通信的其他方式
Reactreact18中组件通信01——props.Reactreact18中组件通信02——消息订阅与发布、取消订阅以及卸载组件时取消订阅.Reactreact18中组件通信03——简单使用 Context 深层传递参数.
1.2 介绍redux
1.2.1 参考官网
讲解、例子参考官网官网地址如下 Redux 中文文档——https://www.redux.org.cn/.
1.2.2 redux原理图
原理图如下 简单解释 要想更新 state 中的数据你需要发起一个 action。Action 就是一个普通 JavaScript 对象注意到没这儿没有任何魔法用来描述发生了什么。强制使用 action 来描述所有变化带来的好处是可以清晰地知道应用中到底发生了什么。如果一些东西改变了就可以知道为什么变。action 就像是描述发生了什么的指示器。最终为了把 action 和 state 串起来开发一些函数这就是 reducer。再次地强调没有任何魔法reducer 只是一个接收 state 和 action并返回新的 state 的函数并且是一个纯函数。而整个应用的 state 被储存在一棵 object tree 中并且这个 object tree 只存在于唯一一个 store 中。
1.2.3 redux基础介绍
1.2.3.1 action
Action 是把数据从应用这里之所以不叫 view 是因为这些数据有可能是服务器响应用户输入或其它非 view 的数据 传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。Action 本质上是 JavaScript 普通对象。我们约定action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下type 会被定义成字符串常量。当应用规模越来越大时建议使用单独的模块或文件来存放 action。
1.2.3.2 store
Store 就是把它们联系到一起的对象。Store 有以下职责 维持应用的 state提供 getState() 方法获取 state提供 dispatch(action) 方法更新 state通过 subscribe(listener) 注册监听器;通过 subscribe(listener) 返回的函数注销监听器。 强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时你应该使用 reducer 组合 而不是创建多个 store。
1.2.3.3 reducer
Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的记住 actions 只是描述了有事情发生了这一事实并没有描述应用如何更新 state。reducer 就是一个纯函数接收旧的 state 和 action返回新的 state。整个应用只有一个单一的 reducer 函数这个函数是传给 createStore 的第一个参数。一个单一的 reducer 最终需要做以下几件事 reducer 第一次被调用的时候state 的值是 undefined。reducer 需要在 action 传入之前提供一个默认的 state 来处理这种情况。reducer 需要先前的 state 和 dispatch 的 action 来决定需要做什么事。假设需要更改数据应该用更新后的数据创建新的对象或数组并返回它们。如果没有什么更改应该返回当前存在的 state 本身。
1.3 安装redux
命令如下npm install --save redux2. redux入门例子
直接从官网拷贝的例子例子地址 https://www.redux.org.cn/.例子如下 import { createStore } from redux;/*** 这是一个 reducer形式为 (state, action) state 的纯函数。* 描述了 action 如何把 state 转变成下一个 state。** state 的形式取决于你可以是基本类型、数组、对象、* 甚至是 Immutable.js 生成的数据结构。惟一的要点是* 当 state 变化时需要返回全新的对象而不是修改传入的参数。** 下面例子使用 switch 语句和字符串来做判断但你可以写帮助类(helper)* 根据不同的约定如方法映射来判断只要适用你的项目即可。*/
function counter(state 0, action) {switch (action.type) {case INCREMENT:return state 1;case DECREMENT:return state - 1;default:return state;}
}// 创建 Redux store 来存放应用的状态。
// API 是 { subscribe, dispatch, getState }。
let store createStore(counter);// 可以手动订阅更新也可以事件绑定到视图层。
store.subscribe(() console.log(store.getState())
);// 改变内部 state 惟一方法是 dispatch 一个 action。
// action 可以被序列化用日记记录和储存下来后期还可以以回放的方式执行
store.dispatch({ type: INCREMENT });// 1
store.dispatch({ type: INCREMENT });// 2
store.dispatch({ type: DECREMENT });// 1效果如下
3. redux入门例子——优化1reducer 和 store拆开
3.1 想要实现的效果 因为上面的简单例子中的state没有在页面上渲染所以简单优化一下实现页面渲染操作想呈现的效果如下 如果用纯react写的话很简单代码如下 import { useState } from react;function CountNum(){const [count,setCount] useState(0);function add(){setCount(count count1);}function subtract(){setCount(count count-1);}return(div当前数字是{count}br /br /button onClick{add}点我 1/button br /br /button onClick{subtract}点我 -1/button/div)
}
export default CountNum;但我们目的是用redux实现所以继续……
3.2 代码设计
项目结构如下 store.js 和 countReducer.js 如下 CountNumRedux.jsx 组件如下 看效果有问题 怎么重新渲染继续……
3.3 添加 重新渲染 使用 useEffect 进行重新渲染核心代码如下 useEffect((){store.subscribe((){console.log(订阅更新打印2-----,store.getState());setCount(store.getState());});
});然后再看效果 关于useEffect 可以看下面的文章 React中组件通信02——消息订阅与发布、取消订阅以及卸载组件时取消订阅.
3.4 附代码 countReducer.js /*** 这是一个 reducer形式为 (state, action) state 的纯函数。* 描述了 action 如何把 state 转变成下一个 state。** state 的形式取决于你可以是基本类型、数组、对象、* 甚至是 Immutable.js 生成的数据结构。惟一的要点是* 当 state 变化时需要返回全新的对象而不是修改传入的参数。** 下面例子使用 switch 语句和字符串来做判断但你可以写帮助类(helper)* 根据不同的约定如方法映射来判断只要适用你的项目即可。*/function countReducer(state 0,action){console.log(state${state}---action${action}---type${action.type});switch (action.type){case INCREMENT:return state 1;case DECREMENT:return state - 1;default:return state;}
}
export default countReducer;store.js import { createStore } from redux;import countReducer from ./countReducer.jsconst store createStore(countReducer);export default store;CountNumRedux.jsx import { useState,useEffect } from react;
import store from ../redux/storefunction CountNumRedux(){const [count,setCount] useState(0);function add(){// setCount(count count1);//派发action 改变内部 state 惟一方法是 dispatch 一个 action。store.dispatch({ type: INCREMENT });}function subtract(){// setCount(count count-1);store.dispatch({ type: DECREMENT });}// 可以手动订阅更新也可以事件绑定到视图层。// store.subscribe(() // console.log(订阅更新打印1-----,store.getState())// );useEffect((){store.subscribe((){console.log(订阅更新,打印2-----,store.getState());setCount(store.getState());});});return(div当前数字是{count} nbsp;nbsp;nbsp;nbsp;当前数字是{store.getState()} br /br /button onClick{add}点我 1/button br /br /button onClick{subtract}点我 -1/button/div)
}export default CountNumRedux;4. redux入门例子——优化2拆出action
4.1 关于action的其他说明
看官网怎么说 Action 本质上是 JavaScript 普通对象。我们约定action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下type 会被定义成字符串常量。当应用规模越来越大时建议使用单独的模块或文件来存放 action。除了 type 字段外action 对象的结构完全由你自己决定。比如下面的 {type: ADD_TODO,text: Build my first Redux app}{type: TOGGLE_TODO,index: 5}更多参考可看https://github.com/redux-utilities/flux-standard-action.在 Redux 中的 action 创建函数只是简单的返回一个 action。如下
4.2 优化——拆出action
根据官网上说的做个简单优化改动点如下 效果就不展示了因为这个还能继续优化如下……
4.3 优化——动态加减数字
4.3.1 优化看效果
如下 效果如下
4.3.2 附代码 代码在上面基础上做了简单的调整action的type抽出了变量直接给代码了如下 countConst.js //定义常量export const INCREMENT INCREMENT; //加
export const DECREMENT DECREMENT; //减countAction.js // //加的时候
// function incrementNum(){
// return { type: INCREMENT };
// }// //减的时候
// function decrementNum(){
// return { type: DECREMENT };
// }import {INCREMENT,DECREMENT} from ./countConst.js//加的时候
function incrementNum(number){return { type: INCREMENT,number:number };
}//减的时候
function decrementNum(number){return { type: DECREMENT,number:number };
}export default{incrementNum,decrementNum}CountNumRedux.jsx import { useState,useEffect,useRef, createRef } from react;
import store from ../redux/store
import countAction from ../redux/countActionfunction CountNumRedux(){const [count,setCount] useState(0);const numberRef createRef();function add(){// setCount(count count1);//派发action 改变内部 state 惟一方法是 dispatch 一个 action。// store.dispatch({ type: INCREMENT });// store.dispatch(countAction.incrementNum());// console.log(numberRef.current.value);let number numberRef.current.value;// console.log(typeof number); //stringstore.dispatch(countAction.incrementNum(parseInt(number)));}function subtract(){let number parseInt(numberRef.current.value);store.dispatch(countAction.decrementNum(number));}useEffect((){store.subscribe((){console.log(订阅更新,打印2-----,store.getState());setCount(store.getState());});});return(div当前数字是{count} nbsp;nbsp;nbsp;nbsp;当前数字是{store.getState()} br /浮动数字input typenumber ref{numberRef}/br /br /button onClick{add}点我 加数/button br /br /button onClick{subtract}点我 减数/button/div)
}export default CountNumRedux;countReducer.js import {INCREMENT,DECREMENT} from ./countConst.jsfunction countReducer(state 0,action){console.log(state${state}---action${action}---type${action.type}---number${action.number});switch (action.type){case INCREMENT:// return state 1;return state action.number;case DECREMENT:// return state - 1;return state - action.number;default:return state;}
}
export default countReducer;