npm i redux react-redux redux-thunk redux-devtools-extension axios (快捷安装)
1.为什么用Redux
(1) Redux是React中最常用的状态管理工具(状态容器)
React只是DOM的一个抽象层(UI库),并不是Web应用的完整解决方案。因此React在涉及到数据的处理以及组件之间的通信时比较复杂
(2) 对于大型的复杂应用来说,只用React,比较吃力

主要的区别:组件之间的通信问题
* 不使用 Redux (图左边) :
* 只能使用父子组件通讯、状态提升等 React 自带机制
* 处理远房亲戚(非父子)关系的组件通讯时乏力
* 组件之间的数据流混乱,出现 Bug 时难定位
* 使用 Redux (图右边):
* **集中式存储和管理应用的状态**
* 处理组件通讯问题时,**无视组件之间的层级关系**
* 简化大型复杂应用中组件之间的通讯问题
* 数据流清晰,易于定位 Bug
redux---------可以运行到任何与js有关的框架,vue,react等
vuex---------只能用到vue
2.redux 安装
npm i redux
3.redux核心概念
(1)核心概念一 =========== action
action:对象,描述要做的事情,项目中的每一个功能都是一个 action
语法:{type:'命令', payload:'载荷'}
特点:1、只描述做什么
2、JS 对象,必须带有 `type` 属性,用于区分动作的类型
3、根据功能的不同,可以携带额外的数据(比如,`payload` 有效载荷,也就是附带的额外的数据),配合该数据来完成相应功能
// action
// 计数器案例
{ type: 'increment' } // +1
{ type: 'decrement' } // -1
// 购物车案例
{ type: 'getGoodsList' }
{ type: 'changeGoodsState', payload: { id: 1, goodsState: true } }
(2)核心概念二 =========== reducer
reducer:函数,用来处理 action 并更新状态,是 Redux 状态更新的地方
语法:函数签名为:`(prevState, action) => newState`
特点:1.注意:该函数一定要有返回值,即使状态没有改变也要返回上一次的状态
2.约定:reducer 是一个纯函数,并且不能包含 side effect 副作用(比如,不能修改函数参数、不能修改函数外部数据、不能进行异步操作等)
3.对于 reducer 来说,为了保证 reducer 是一个纯函数,不要:
* 不要直接修改参数 state 的值(也就是:不要直接修改当前状态,而是根据当前状态值创建新的状态值)
* 不要使用 Math.random() / new Date() / Date.now() / ajax 请求等不纯的操作
* 不要让 reducer 执行副作用(side effect)
// 干活:reducer创建store使用
// 初始值
const initialState = {
num: 0
}
export function numReducer (state = initialState, action) {
let newState = { ...state }
switch (action.type) {
case ADD:
newState.num++
return newState
case SUB:
newState.num--
return newState
default:
return state
}
}
(3)核心概念三 =========== store
store:仓库,Redux 的核心,整合 action 和 reducer
特点:1.一个应用只有一个store
2.维护应用的状态,获取状态:store.getState()
3.发起状态更新时:store.dispatch(action)
4.创建 store 时**接收 reducer 作为参数**:const store = createStore(reducer)
其他api:
1.订阅(监听)状态变化:const unSubscribe = store.subscribe(() => {})
2.取消订阅状态变化: unSubscribe()
// 创建 store
// 参数为:reducer 函数
const store = createStore(numReducer)
// 监听状态变化
const unSubscribe = store.subscribe(() => {
// 状态改变时,执行相应操作
// 比如,记录 redux 状态
console.log(1, store.getState())
})
// 取消监听状态变化
// unSubscribe()
// 发布命令(action),执行reducer干活
store.dispatch(addAction())
store.dispatch(addAction())
store.dispatch(addAction())
核心概念整合----小案例(index.js)
import { createStore } from "redux";
// 加/减
// 命令:动作
const ADD = "ADD",
SUB = "SUB";
// 修改state状态会使用
export function addAction(payload) {
return {
type: ADD,
payload,
};
}
export function subAction(payload) {
return {
type: SUB,
payload,
};
}
// 干活:reducer创建store使用
// 初始值
const initialState = {
num: 0,
};
export function numReducer(state = initialState, action) {
let newState = { ...state };
switch (action.type) {
case ADD:
newState.num+=action.payload;
return newState;
case SUB:
newState.num--;
return newState;
default:
return state;
}
}
// 3. 创建 store
// 参数为:reducer 函数
const store = createStore(numReducer);
console.log("状态值为:",store, store.getState());
// 监控状态值的变化
const un=store.subscribe(() => {
console.log('状态变化了',store.getState());
})
// 取消监控
un()
// 发起更新状态:
// 参数: action 对象
store.dispatch(addAction(10));
store.dispatch(addAction(10));
store.dispatch(subAction());
// 相当于: reducer(10, { type: 'increment' })
console.log("更新后:", store,store.getState());
4.react-redux介绍
问题:为什么要使用React-Redux绑定库?
回答:React和Redux是两个独立的库,两者之间职责独立。因此,为了实现再React中使用Redux进行状态管理,需要一种机制,将这两个独立的库关联在一起。
作用:为React接入Redux,实现在React中使用Redux进行状态管理
react-redux库是Redux官方提供的React绑定库
5.react-redux 基本使用
react-redux的使用分两大步:1.全局配置(只需要配置一次,在src/index.js中) 2.组件接入(获取状态或修改状态)
步骤:1.安装 react-redux (npm install react-redux)
2.从 react-redux 中导入 Provider 组件(全局配置中,传递数据)
3.导入创建好的 redux 仓库 (内部包含action ,reducer, store)
4.使用 Provider 包裹整个应用
5.将导入的 store 设置为 Provider 的 store 属性值
核心代码:src/index.js
import ReactDOM from "react-dom";
import App from "./test";
// 导入 Provider 组件(提供store)
import { Provider } from "react-redux";
// 导入创建好的 store
import store from "./store";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
6. react-redux 获取状态 useSelector
useSelector : 获取 Redux 提供的状态数据
参数:selector 函数,用于从 Redux 状态中筛选出需要的状态数据并返回
返回值:筛选出的状态
import { useSelector } from 'react-redux'
// 计数器案例中,Redux 中的状态是数值,所以,可以直接返回 state 本身
const count = useSelector(state => state)// 比如,Redux 中的状态是个对象,就可以:
const list = useSelector(state => state.list)
import { useSelector } from "react-redux"
function App(){
// 获取 store 数据
const count=useSelector(state=>state.num)
console.log('获取到的store数据',count);
return(
<div>
<ul>
<li>值:{count}</li>
<li></li>
<li></li>
</ul>
</div>
)
}
export default App
7.react-redux 分发动作 useDispatch
useDispatch: 拿到 dispatch 函数,分发action,修改redux中的状态
import { useDispatch } from 'react-redux'
// 调用 useDispatch hook,拿到 dispatch 函数
const dispatch = useDispatch()// 调用 dispatch 传入 action,来分发动作
dispatch( action )
import { useDispatch, useSelector } from "react-redux"
function App(){
// 获取 store 数据
const count=useSelector(state=>state.num)
console.log('获取到的store数据',count);
// 修改状态
const dispatch=useDispatch()
return(
<div>
<ul>
<li>值:{count}</li>
<li>
<button onClick={()=>dispatch({type:'ADD',payload:5})}>+</button>
</li>
<li>
<button onClick={()=>dispatch({type:'SUB'})}>-</button>
</li>
</ul>
</div>
)
}
export default App
redux 数据流

8.redux------reducer合并
1. src/store/actions------新建count.js
// 加/减
// 命令:动作
// 修改state状态会使用
export function addAction(payload) {
return {
type: 'ADD',
payload,
};
}
export function subAction(payload) {
return {
type: 'SUB',
payload,
};
}
2. src/store/reducers---------新建count.js
// 干活:reducer创建store使用
// 初始值
const initialState = {
num: 0,
};
export function numReducer(state = initialState, action) {
let newState = { ...state };
switch (action.type) {
case 'ADD':
newState.num += action.payload;
return newState;
case 'SUB':
newState.num--;
return newState;
default:
return state;
}
}
3. src/store/reducers-------新建 list.js
// 干活:reducer创建store使用
// 初始值
export function listReducer(state = [1, 2, 3], action) {
switch (action.type) {
case "SUB":
return [...state, 4];
default:
return state;
}
}
4. src/store/reducers------新建 index.js(将count和list合并)
import { combineReducers } from "redux";
// 导入要合并的reducer函数
import { numReducer } from "./count";
import { listReducer } from "./list";
export const rootReducer = combineReducers({
numReducer,
listReducer
})
5.src/store/index----- store(抛出)
import { createStore } from "redux";
import { rootReducer } from "./reducers";
// 3. 创建 store
// 参数为:reducer 函数
const store = createStore(rootReducer);
export default store;
7.src/index----------store(全局挂载)
import ReactDOM from "react-dom";
import App from "./test";
// 导入 Provider 组件(提供store)
import { Provider } from "react-redux";
// 导入创建好的 store
import store from "./store";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
8.页面渲染显示-------test.js
import { useDispatch, useSelector } from "react-redux"
import {addAction,subAction} from './store/actions/count'
function App(){
// 获取 count 数据
const count=useSelector(state=>state.numReducer.num)
console.log('获取count数据',count);
// 获取list数据
const list=useSelector(state=>state.listReducer)
console.log('获取list数据',list);
// 修改状态
const dispatch=useDispatch()
return(
<div>
<ul>
<li>值:{count}</li>
<li>
<button onClick={()=>dispatch(addAction(5))}>+</button>
</li>
<li>
<button onClick={()=>dispatch(subAction())}>-</button>
</li>
{
list.map(item=>{
return <li>{item}</li>
})
}
</ul>
</div>
)
}
export default App
src/store/index.js-----模板
import { createStore, applyMiddleware } from 'redux'
import rootReducer from './reducers'
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension'
const middlewares = composeWithDevTools(applyMiddleware(thunk))
const store = createStore(rootReducer, middlewares)
export default store
本文围绕Redux和React-Redux展开,介绍了Redux作为React常用状态管理工具的优势,如集中存储管理状态、简化组件通讯等。还阐述了Redux的安装、核心概念(action、reducer、store),以及React-Redux的作用、基本使用步骤,包括获取状态和分发动作等内容。

889

被折叠的 条评论
为什么被折叠?



