[react] Redux基本介绍 ===
目录
redux 是什么?
redux 和 react 的关系
为什么Rect要用 Redux
react 多组件共享 - 案例
使用redux来解决的思路
Redux 三个核心概念
理解三个核心概念
action
reducer
store
Redux功能演示核心代码
store 相关API
Redux 代码执行过程
解决问题-redux在react中使用
redux 是什么?
Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理。
当遇到如下问题时,建议开始使用 Redux:
你有很多数据随时间而变化
你希望状态有一个唯一确定的来源
你发现将所有状态放在顶层组件中管理已不可维护
redux 和 react 的关系
Redux并不只为react应用提供状态管理, 它还支持其它的框架。
为什么Rect要用 Redux
React 是 DOM 的一个抽象层(UI 库),并不是 Web 应用的完整解决方案。因此react在涉及到数据的处理以及组件之间的通信时会比较复杂。
对于大型的复杂应用来说,这两方面恰恰是最关键的。因此,只用 React,写大型应用比较吃力。
2014 年 Facebook 提出了 Flux 架构的概念,引发了很多的实现。
2015 年,Redux 出现,将 Flux 与函数式编程(reducer)结合一起,很短时间内就成为了最热门的前端架构。
Flux 是最早的状态管理 工具,它提供了状态管理的思想,也提供对应的实现
除了 Flux、Redux 之外,还有:Mobx 等状态管理工具
主要的区别:组件之间的通讯问题
不使用 Redux (图左边) :
只能使用父子组件通讯、状态提升等 React 自带机制
处理远房亲戚(非父子)关系的组件通讯时乏力
组件之间的数据流混乱,出现 Bug 时难定位
使用 Redux (图右边):
集中式存储和管理应用的状态
处理组件通讯问题时,无视组件之间的层级关系
简化大型复杂应用中组件之间的通讯问题
数据流清晰,易于定位 Bug
react 多组件共享 - 案例
问题描述
多组件(跨层级的)共享数据
目录结构
├── src
├── store # redux目录,一般约定叫store
│ ├── index.js # 定义并导出store. 其中会导入reducer
│ └── reducer # reducer函数
├── App.js # 根组件,引入Father 和 Uncle组件
├── Father.js # Father组件。其中引入了Son组件
├── index.js # 项目的入口文件,会导入并渲染App.js
├── Son.js # Son组件
└── Uncle.js # Unclde组件
使用redux来解决的思路
redux可以无视组件层级
对于组件系统来说,redux就是一个第三方的,全局的变量
Redux 三个核心概念
图示
理解三个核心概念
核心概念:store
、action
、reducer
action
动作。
一个js对象,包含两个属性:
type: 标识属性,值是字符串。多个type用action分开
payload:数据属性,可选。表示本次动作携带的数据
actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
特点:
只描述做什么
JS 对象,必须带有
type
属性,用于区分动作的类型根据功能的不同,可以携带额外的数据,配合该数据来完成相应功能
示例:
{ type: 'increment' }
{ type: 'decrement', count: 2 }
{ type: 'addTodo', name: '吃饭' }
{ type: 'removeTodo', id: 3 }{ type: 'addN', payload: n }
{ type: 'addN', payload: {count:2} }
{ type: 'addN', payload: {name:'吃饭',age:18} }
reducer
一个函数
作用
初始化状态
修改状态
修改状态
根据传入的旧状态和action,返回新状态
公式:
(previousState, action) => newState
示例
const reducer = (state = 0, action) => {switch (action.type) {case 'add':// 返回新的statereturn state + 1case 'addN':// 返回新的statereturn state + action.payloaddefault:return state}
}
store
store:仓库,Redux 的核心,整合 action 和 reducer
特点:
一个应用只有一个 store
维护应用的状态,获取状态:
store.getState()
创建 store 时接收 reducer 作为参数:
const store = createStore(reducer)
发起状态更新时,需要分发 action:
store.dispatch(action)
其他 API, — 订阅(监听)状态变化:
const unSubscribe = store.subscribe(() => {})
— 取消订阅状态变化:unSubscribe()
Redux功能演示核心代码
定义reuder
initState = 0
function reducer(state = initState, action) {return state
}
定义action
const action1 = { type:'addN', payload: 12 }
// store.dispatch(action1)const action2 = { type:'add', payload: 1 }
定义store
import { createStore } from 'redux'
// 创建 store
const store = createStore(reducer)
store 相关API
store获取状态
store.getState()
store修改数据,通过派发action。
store.dispatch({type:xxx, payload: xx}})
store添加订阅者。
// 格式:
// 取消订阅 = store.subscribe(订阅者)// 订阅者:就是一个函数,当state值变化时,store会执行它
// store.subscript()的返回值也是一个函数,执行它时,它的
const unSubscribe = store.subscribe(() => {// 状态改变时,执行相应操作
})// 取消监听状态变化
4. 取消订阅者。unSubscribe()
核心代码
import { createStore } from 'redux'initState = 0
function reducer(state = initState, action) {return state
}
// 创建 store
const store = createStore(reducer)// store获取状态
console.log(store.getState())// 更新状态
// 1. dispatch 派遣,派出。表示:分发一个 action,也就是发起状态更新
// 2. store.dispatch会 调用reducer函数,并将action传递给reducer
const action1 = { type:'addN', payload: 12 }
store.dispatch(action1)const action2 = { type:'add', payload: 1 }
store.dispatch(action2)// store 添加订阅者
// store.subscribe
// 订阅者:就是一个函数,当state值变化时,store会执行它
const unSubscribe = store.subscribe(() => {// 状态改变时,执行相应操作console.log('数据变化了....')
})// 取消监听状态变化
unSubscribe()
Redux 代码执行过程
获取默认值
只要创建 store,那么,Redux 就会调用一次 reducer, 且type是一个随机值。如下是一个示例:
这一次调用 reducer 的目的:获取状态的默认值。这个初始值将成为下一次调用 store.getState()
方法来获取 Redux 状态值的preState
type是随机值确保了它不会被用户业务逻辑处理,而只能去匹配默认值。
更新状态
当你需要更新状态时,就先分发动作
store.dispatch(action)
Redux 内部,store 就会调用 reducer,传入:上一次的状态(当前示例中就是:
0
)和 action({ type: 'add' }
),计算出新的状态,并返回reducer 执行完毕后,将最新的状态交给 store,store 用最新的状态替换旧状态,状态更新完毕
import { createStore } from 'redux'
const store = createStore(reducer)function reducer(state = 0, action) {console.log('reducer:', state, action)switch (action.type) {case 'add':return state + 1default:return state}
}console.log('状态值为:', store.getState()) // 10// 发起更新状态:
// 参数: action 对象
store.dispatch({ type: 'increment' })
// 相当于: reducer(10, { type: 'increment' })console.log('更新后:', store.getState()) // 11
解决问题-redux在react中使用
├── src
├── store # redux目录,一般约定叫store
│ ├── index.js # 定义并导出store. 其中会导入reducer
│ └── reducer # reducer函数
├── App.js # 根组件,引入Father 和 Uncle组件
├── Father.js # Father组件。其中引入了Son组件
├── index.js # 项目的入口文件,会导入并渲染App.js
├── Son.js # Son组件
└── Uncle.js # Unclde组件
store/index.js
用reducer来初始化store
import { createStore } from 'redux'
import reducer from './reducer'
export default createStore(reducer)
reducer.js
设置初始值,并提供修改数据的逻辑
const initState = 0
export default function reducer (state = initState, action) {console.log(action)switch (action.type) {case 'addN':return state + action.payloadcase 'sub':return state - 1default:return state}
}
src/index.js
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'import store from './store/index.js'
ReactDom.render(<App />, document.getElementById('root'))// 数据变化时,重新渲染
store.subscribe(() => {ReactDom.render(<App />, document.getElementById('root'))
})
src/App.js
import React from 'react'
import Father from './Father'
import Uncle from './Uncle'
export default function App () {return (<div style={{ border: '1px solid #ccc', margin: 10, padding: 10 }}>根组件<Father /><Uncle /></div>)
}
son.js
获取数据: store.getState()
修改数据: store.dispatch(action)
import React, { useState } from 'react'
import store from './store/index'
export default function Son () {const [n, setN] = useState(12)const add = () => {store.dispatch({ type: 'addN', payload: n })}return (<div style={{ border: '1px solid #ccc', margin: 10, padding: 10 }}>子组件{store.getState()}<button onClick={add}>+n</button><input value={n} onChange={(e) => setN(e.target.value)} /></div>)
}
uncle.js
修改数据: store.dispatch(action)
import React from 'react'
import store from './store/index'
export default function Uncle () {return (<div style={{ border: '1px solid #ccc', margin: 10, padding: 10 }}>Uncle组件<buttononClick={() => {store.dispatch({ type: 'sub' })}}>-1</button></div>)
}
[react] Redux基本介绍 ===相关推荐
- webpack+react+redux+es6开发模式---续
一.前言 之前介绍了webpack+react+redux+es6开发模式 ,这个项目对于一个独立的功能节点来说是没有问题的.假如伴随着源源不断的需求,前段项目会涌现出更多的功能节点,需要独立部署运行 ...
- webpack+react+redux+es6开发模式
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- 一个 react+redux 工程实例
在前几天的一篇文章中总结部分提到了学习过程中基础的重要性.当然,并不是不支持大家学习新的框架,这篇文章就分享一下react+redux工程实例. 一直在学习研究react.js,前前后后做了几次分享. ...
- React Redux: 从文档看源码 - Components篇
注:这篇文章只是讲解React Redux这一层,并不包含Redux部分.Redux有计划去学习,等以后学习了Redux源码以后再做分析 注:代码基于现在(2016.12.29)React Redux ...
- 实例讲解基于 React+Redux 的前端开发流程
前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 star 数达 42000 +,超过了 jquery 的 39000+,也即将超过前几年比较火的an ...
- React + Redux + Express + Mongodb 零基础开发完整大型商城网站视频教程(97 个视频)
React + Redux + Express + Mongodb 零基础开发完整大型商城网站视频教程(97 个视频) mern 架构零基础开发完整电商网站 React + Redux + Expre ...
- 用 React+Redux+Immutable 做俄罗斯方块
俄罗斯方块是一直各类程序语言热衷实现的经典游戏,JavsScript的实现版本也有很多,用React 做好俄罗斯方块则成了我一个目标. 戳 https://chvin.github.io/react- ...
- react+redux实战——redux到底是个啥子?
写在前面 文章是个人初学redux的分享,从redux基础知识点到使用redux搭建简单的表单提交项目. 项目代码地址:https://github.com/jishuaizhen/react-red ...
- React+Redux技术栈核心要点解析(上篇)
感谢作者郭永峰的授权发布. 作者:郭永峰,前端架构师,现用友网络 FED团队负责人,目前主要负责企业级应用前端技术平台建设工作,在前端工程化实现.Node 应用开发.React技术.移动开发等方向有丰 ...
最新文章
- html 360shiyanshi,360发布国内首个HTML5实验室 4大特性抢先测
- 自学python可以找到好的工作吗-27岁0基础自学Python,多久可以找到工作?
- Unity InvalidOperationException: out of sync错误
- sqoop 增量导入,不重复
- C++ Primer 5th笔记(chap 19 特殊工具与技术)枚举类型
- 推荐一个MDI模式的远程桌面管理程序
- api 原生hbase_Hbase常用api
- java 泛型集合示例_Java 泛型(示例代码)
- java volatile详解,互联网 面试官 如何面试
- mysql将日期转换年份_mysql将日期转换为当前年份的相同日期
- js去除字符串头尾空格
- amcharts php,amcharts实现动态数据介绍
- 智能停车场车牌识别计费系统
- 《计算机网络技术》第一章测试(题目及答案)
- APP运营精华:6种营销推广模式
- 京瓷p5021cdn快速复印_功率实测 节能出色_京瓷 P5021cdn_办公打印评测试用-中关村在线...
- python对红楼梦的每一章节进行词频统计
- Shopee大规模毁约offer,今年的大厂装都不装了
- realme闪充技术令外媒惊叹,国产手机靠创新打破苹果垄断
- RGB 与 (RGB转 YCbCr再转为 RGB)的图像
热门文章
- qr-code 生成二维码
- html原生select 下拉框
- Windows10下Vmware15.5虚拟机安装苹果的10.15.5(19F96)CDR镜像
- #今日论文推荐# ICDE 2022 | 港大等提出:基于时空自监督学习的犯罪预测
- 基于kotlin实现的简单个人账户管理APP
- Raphael绘制流程图(一),添加可拖动的图形
- 多媒体技术(大计基复习资料)
- java堆数据的进出原则是,堆栈数据的进出原则是()
- Revit连接Access数据库
- set函数python作用_pythonset函数是什么