基本介绍
相信Provider和Consumer以及满足不了大家在跨组件传值的需求了,非常希望有像vue中vuex那种非常便捷的传值方式(虽然尤雨溪大神说vuex要被弃用)
那这里就来给大家react中主流使用的通讯方式
内容比较干,但都是实货
大致介绍有如下五种
- Redux并不只为react应用提供状态管理, 它还支持其它的框架。
-
集中式存储和管理应用的状态
-
处理组件通讯问题时,无视组件之间的层级关系
-
简化大型复杂应用中组件之间的通讯问题
-
数据流清晰,易于定位 Bug
主要俩点:集中式存储和管理应用的状态:无视组件之间的层级关系
Redux 三个核心概念
Action · Reduxhttps://www.redux.org.cn/docs/basics/Actions.html以上是官网 但是我感觉官网有些话就不是人来理解的 所以以下是我个人理解
action概述
- Action 本质上是 JavaScript 普通对象
- 它是 store 数据的唯一来源
- action 内第一参数必须使用一个字符串类型的
type
字段来表示将要执行的动作 -
第二参数:数据属性,可选。表示本次动作携带的数据
-
actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
-
特点:
-
只描述做什么
-
JS 对象,必须带有
type
属性,用于区分动作的类型 -
根据功能的不同,可以携带额外的数据,配合该数据来完成相应功能
-
示例
{
type: TOGGLE_TODO,
index: 5
}
reducer概述
-
一个函数
-
actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
-
作用
- 初始化状态
- 修改状态
-
修改状态
根据传入的旧状态和action,返回新状态
公式:
(previousState, action) => newState
const reducer = (state = 0, action) => {
switch (action.type) {
case 'add':
// 返回新的state
return state + 1
case 'addN':
// 返回新的state
return state + action.payload
default:
return state
}
}
store概述
-
store:仓库,Redux 的核心,整合 action 和 reducer
-
特点:
-
一个应用只有一个 store
-
维护应用的状态,获取状态:
store.getState()
-
创建 store 时接收 reducer 作为参数:
const store = createStore(reducer)
-
发起状态更新时,需要分发 action:
store.dispatch(
{type:xxx, payload: xx})
-
-
其他 API, — 订阅(监听)状态变化:
const unSubscribe = store.subscribe(() => {})
— 取消订阅状态变化:unSubscribe()
相信看到这里大家也还是一脸懵逼,现在就来演示一下
演示
我们创建一个以下的一个结构进行介绍
├── src
├── store # redux目录,一般约定叫store
│ ├── index.js # 定义并导出store. 其中会导入reducer
│ └── reducer.js # reducer函数
├── App.js # 根组件,引入Father 和 Uncle组件
├── Father.js # Father组件。其中引入了Son组件
├── index.js # 项目的入口文件,会导入并渲染App.js
├── Son.js # Son组件
└── Uncle.js # Unclde组件
怎么搭这个壳子大家搭好后就开始我们接下来的步骤了
第一步 下包
npm i redux
第二步 store/index.js 中 用reducer来初始化store
import { createStore } from 'redux'
import reducer from './reducer'
export default createStore(reducer)
第三步 在reducer.js中 设置初始值,并提供修改数据的逻辑
export default function reducer (state = 0, action) {
console.log(action)
switch (action.type) {
case 'addN':
return state + action.payload
case 'sub':
return state - 1
default:
return state
}
}
第四步 在根节点 src/index.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与uncle组件中使用和修改值
获取数据:store.getState()
修改数据:store.dispatch(action)
例如下面 在son中使用
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>
)
}
如此便大功告成了!
弊端
可以发现由于在根节点调用了订阅(监听)状态变化 所以每一次修改数据都会导致页面重新加载,小项目还好,在大项目中这样根本就行不通,为了解决这个问题,于是有大神便集成了redux,做了一个专属于react的集中状态管理的插件,react-redux那下一篇 我将为大家详细介绍一下react-redux