在react项目开发中,我们常常会用到 redux,可是每次我们都要创建很多文件夹和繁琐的配置,今天就分享一个傻瓜式搭建(会CV就行)
说明
redux是一个第三方的集中管理数据的库。
- 小。2kb
- 强。功能强大
- 广。并不限于react:单独可以用,也可以和其他的框架配合。
- 不是必需的。
基本介绍
概念
redux是一个专门用于做状态管理的JS库(不是react专用的)
作用:集中管理公共状态(多个组件都要使用)。
Redux 是 react 中最流行的状态管理工具之一(flux, redux,mobx) 。
起源
React 只是 DOM 的一个抽象层(UI 库),并不是 Web 应用的完整解决方案。因此react在涉及到数据的处理以及组件之间的通信时会比较复杂。
- 对于大型的复杂应用来说,这两方面恰恰是最关键的。因此,只用 React,写大型应用比较吃力。
- 2014 年 Facebook 提出了 Flux 架构的概念,引发了很多的实现。reducer + flux ==> redux
- 2015 年,Redux 出现,将 Flux 与函数式编程(reducer)结合一起,很短时间内就成为了最热门的前端架构。
- Flux 是最早的状态管理 工具,它提供了状态管理的思想,也提供对应的实现
- 除了 Flux、Redux 之外,还有:Mobx 等状态管理工具
什么时候使用 redux
官方表述:如果你不知道是否需要 Redux,那就是不需要它。只有遇到 React 实在解决不了的问题,你才需要 Redux。
小项目用不上。
react 技术栈
- react 核心 react hooks
- react-router(react-router-dom)
- 状态管理: mobx(简单)/ redux(复杂) ----中间件: redux-thunk redux-saga
Redux 三个核心概念
1.action
-
动作。
-
一个js对象,包含两个属性:
- type: 标识属性,值是字符串。多个type用action分开
- payload:数据属性,可选。表示本次动作携带的数据
-
actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
-
特点:
- 只描述做什么
- JS 对象,必须带有
type
属性,用于区分动作的类型 - 根据功能的不同,可以携带额外的数据,配合该数据来完成相应功能
{ type: 'add1' }
{ type: 'addN', payload:10 }
2.reducer
-
一个纯函数
-
作用
-
- 初始化状态
- 修改状态
-
-
修改状态
根据传入的旧状态和action,返回新状态
公式:
(previousState, action) => newState
const reducer = (state = 0, action) => {
switch (action.type) {
// 执行动作add 让state 加1
case 'add':
// 返回新的state
return state + 1
case 'addN':
// 返回新的state
return state + action.payload
default:
return state
}
}
3.store
-
store:仓库,Redux 的核心,整合 action 和 reducer
-
特点:
- 一个应用只有一个 store
- 维护应用的状态,获取状态:
store.getState()
- 创建 store 时接收 reducer 作为参数:
const store = createStore(reducer)
- 发起状态更新时,需要分发 action:
store.dispatch(action)
其他 API:这里一般使用
react-redux
库代替):
— 订阅(监听)状态变化:const unSubscribe = store.subscribe(() => {})
— 取消订阅状态变化:
unSubscribe()
import { createStore } from 'redux'
import reducer from './reducer'
export default createStore(reducer)
目标
- 在react项目中配置redux
步骤
1.先下包
npm i redux react-redux redux-devtools-extension redux-thunk
说明
redux: 一个第三方的集中管理数据的库。
react-redux: 官方 React 绑定。
redux-devtools-extension: Redux DevTools 扩展的助手(调试redux)
redux-thunk: Redux 的Thunk[中间件] 它允许编写具有内部逻辑的函数,这些函数可以与 Redux 存储`dispatch`和`getState`方法进行交互。
redux-logger: 查看redux的操作日志(有调试工具了这个可以不装)
2.创建文件夹
├── src
├── store # redux目录,一般约定叫store
| ├── index.js # 定义并导出store. 其中会导入reducer
|
| └── actions # 多个模块的action
| ├── action1.js # 模块1的 相关action creator
| ├── action2.js # 模块2的 相关action creator
| └── index.js # 合并 action creator
|
| └── reducers # 多个模块的reducer
| ├── reducer1.js # 模块1的reducer
| ├── reducer2.js # 模块2的reducer
| └── index.js # reducer的整体入口,会导入reducer1, reducer2
|
| └── actionTypes
| ├── actionType1.js # 模块1的actionType
| ├── actionType2.js # 模块2的actionType
|
├── index.js # 项目的入口文件,会导入并渲染App.js
├── App.js # 根组件,引入模块1 和模块2 组件
|
|── Pages
├── 模块1.js # 模块1 组件
└── 模块2.js # 模块2 组件
3.配置
入口文件index.js
import App from './App'
import ReactDOM from 'react-dom'
import './styles/index.css'
// Provider包裹根组件App就不需要每个组件都引入store了
import { Provider } from 'react-redux'
import store from './store'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
srr/store/index
// applyMiddleware(中间件1,中间件2)使用中间件
import { createStore, applyMiddleware } from 'redux'
// thunk中间件 dispath()能够传入函数执行异步请求\
import thunk from 'redux-thunk'
// composeWithDevTools() redux调试工具
import { composeWithDevTools } from 'redux-devtools-extension'
// 合并后的reducer
import rootReducer from './reducers/index'
// 创建store 传入合并后的reducer
const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(thunk))
)
export default store
reducer/index.js
// channel和newList组件的reducer
import channel from './channel'
import newList from './newList'
// combineReducers 合并各个reducer
import { combineReducers } from 'redux'
const rootReducer = combineReducers({
channel,
newList
})
export default rootReducer