Redux是一个状态管理器,通常与React一起使用,但它并不与该库绑定。通过阅读此简单易懂的指南来学习Redux
为什么需要Redux
Redux是一个状态管理器,通常与React一起使用,但它并不与该库绑定-它也可以与其他技术一起使用,但是为了说明起见,我们将坚持使用React。
如您所读,React有其自己的状态管理方式。React初学者指南在这里,我介绍了如何在React中管理状态。
在简单的情况下,将状态在树中上移是可行的,但是在复杂的应用程序中,您可能会发现几乎使用道具向上移动所有状态,然后向下向下移动道具。
React在16.3.0版中引入了上下文API,这使得Redux在从应用程序的不同部分访问状态的用例中变得多余,因此,除非您需要Redux提供的特定功能,否则请考虑使用Context API而不是Redux。
Redux是一种管理应用程序状态并将其移至外部全球商店。
您需要掌握一些概念,但是一旦完成,Redux是解决问题的非常简单的方法。
Redux在React应用程序中非常流行,但是它绝不是React独有的:几乎所有流行的框架都有绑定。就是说,我将使用React作为它的主要用例来举例说明。
什么时候应该使用Redux?
Redux是中型到大型应用程序的理想选择,只有在使用默认状态管理React或其他使用的库来管理状态时,才应使用Redux。
简单的应用程序根本不需要它(简单应用程序没有错)。
不变的状态树
在Redux中,应用程序的整个状态表示为一 JavaScript对象,称为状态或者状态树。
我们称它为不变的状态树因为它是只读的:不能直接更改。
只能通过分派一个行动。
动作
一个行动是一个以最小方式描述更改的JavaScript对象(仅提供所需的信息):
{
type: 'CLICKED_SIDEBAR'
}
// e.g. with more data
{
type: ‘SELECTED_USER’,
userId: 232
}
动作对象的唯一要求是拥有一个type
属性,其值通常是一个字符串。
动作类型应为常量
在简单的应用程序中,可以将操作类型定义为字符串。
当应用增长时,最好使用常量:
const ADD_ITEM = 'ADD_ITEM'
const action = { type: ADD_ITEM, title: 'Third item' }
并在自己的文件中分离操作,然后将其导入
import { ADD_ITEM, REMOVE_ITEM } from './actions'
动作创作者
动作创作者是创建动作的功能。
function addItem(t) {
return {
type: ADD_ITEM,
title: t
}
}
通常,您可以结合触发调度程序来运行动作创建者:
dispatch(addItem('Milk'))
或通过定义动作分派器功能:
const dispatchAddItem = i => dispatch(addItem(i))
dispatchAddItem('Milk')
减速器
当一个动作被触发时,必须发生一些事情,应用程序的状态必须改变。
这是工作减速器。
什么是减速器
一种减速器是一个纯功能它根据前一个状态树和分派的操作来计算下一个状态树。
;(currentState, action) => newState
纯函数接受输入并返回输出,而不更改输入或其他任何内容。因此,reducer返回一个全新的状态来替代先前的状态。
减速器不应该做什么
减速器应为纯函数,因此应:
- 永不改变其论点
- 永远不会改变状态,而是创建一个新的状态
Object.assign({}, ...)
- 永远不会产生副作用(没有API调用会改变任何东西)
- 永远不要调用非纯函数,这些函数会根据输入以外的因素来改变其输出(例如,
Date.now()
或者Math.random()
)
没有强化,但是您应该遵守规则。
多个异径管
由于复杂应用程序的状态可能真的很宽,因此没有单个化简器,而是针对任何类型的动作使用了许多化简器。
减速器的模拟
本质上,Redux可以通过以下简单模型进行简化:
状态
{
list: [
{ title: "First item" },
{ title: "Second item" },
],
title: 'Groceries list'
}
行动清单
{ type: 'ADD_ITEM', title: 'Third item' }
{ type: 'REMOVE_ITEM', index: 1 }
{ type: 'CHANGE_LIST_TITLE', title: 'Road trip list' }
每个州的减速器
const title = (state = '', action) => {
if (action.type === 'CHANGE_LIST_TITLE') {
return action.title
} else {
return state
}
}
const list = (state = [], action) => {
switch (action.type) {
case ‘ADD_ITEM’:
return state.concat([{ title: action.title }])
case ‘REMOVE_ITEM’:
return state.filter(item =>
action.index !== item.index)
default:
return state
}
}
整个状态的减速器
const listManager = (state = {}, action) => {
return {
title: title(state.title, action),
list: list(state.list, action)
}
}
商店
这店铺是一个对象:
- 保持状态该应用程序的
- 暴露状态通过
getState()
- 允许我们更新状态通过
dispatch()
- 允许我们(取消)注册状态变更监听器使用
subscribe()
一家商店是独特的在应用程序中。
这是为listManager应用程序创建商店的方式:
import { createStore } from 'redux'
import listManager from './reducers'
let store = createStore(listManager)
我可以使用服务器端数据初始化存储吗?
当然,刚过一个开始状态:
let store = createStore(listManager, preexistingState)
获取状态
store.getState()
更新状态
store.dispatch(addItem('Something'))
聆听状态变化
const unsubscribe = store.subscribe(() =>
const newState = store.getState()
)
unsubscribe()
数据流
Redux中的数据流始终是单向。
你打电话dispatch()
在商店中,通过一个动作。
商店负责将操作传递给Reducer,生成下一个状态。
商店会更新状态并警告所有侦听器。
免费下载我的反应手册
更多反应教程:
- 一个React简单的应用示例:通过API获取GitHub用户信息
- 用React构建一个简单的计数器
- 用于React开发的VS代码设置
- 如何通过React Router将道具传递给子组件
- 使用Electron和React创建一个应用
- 教程:使用React创建电子表格
- 学习React的路线图
- 了解如何使用Redux
- JSX入门
- 样式化的组件
- Redux Saga简介
- React Router简介
- React简介
- 反应组件
- 虚拟DOM
- 反应事件
- 反应状态
- 反应道具
- 反应片段
- React Context API
- 反应PropTypes
- 反应概念:声明式
- React:如何在点击时显示其他组件
- 如何在React JSX内部循环
- 道具与状态在React中
- 您应该使用jQuery还是React?
- 使用React需要知道多少JavaScript?
- 盖茨比介绍
- 如何在React中引用DOM元素
- React中的单向数据流
- 反应高阶组件
- 反应生命周期事件
- 反应概念:不变性
- 反应概念:纯度
- React钩子简介
- create-react-app简介
- 反应概念:组成
- React:演示组件与容器组件
- React中的代码拆分
- 使用React进行服务器端渲染
- 如何安装React
- React中的CSS
- 在React中使用SASS
- 在React中处理表单
- 反应严格模式
- 反应门户
- 反应渲染道具
- 测试React组件
- 如何在React中将参数传递给事件处理程序
- 如何处理React中的错误
- 如何在JSX中返回多个元素
- React中的条件渲染
- 反应,如何将道具转移到子组件
- 如何在React中获取输入元素的值
- 如何使用useState React钩子
- 如何使用useCallback React钩子
- 如何使用useEffect React钩子
- 如何使用useMemo React钩子
- 如何使用useRef React钩子
- 如何使用useContext React钩子
- 如何使用useReducer React钩子
- 如何将您的React应用程序连接到相同来源的后端
- 到达路由器教程
- 如何使用React Developer Tools
- 如何学习React
- 如何调试React应用程序
- 如何在React中呈现HTML
- 如何修复`dangerouslySetInnerHTML`与React中的错误不匹配
- 我如何解决React登录表单状态和浏览器自动填充的问题
- 如何在本地主机上的React应用程序中配置HTTPS
- 如何修复React中的“渲染其他组件时无法更新组件”错误
- 我可以在条件内使用React挂钩吗?
- 将useState与对象一起使用:如何更新
- 如何使用React和Tailwind在代码块中移动
- React,添加到DOM时将焦点放在React中的一个项目上
- 反应,在doubleclick上编辑文本