redux
Redux 是 React 最常用的集中状态管理工具,类似于 Vue 中的 Pina/Vuex, 可以独立于框架运行。
作用:通过集中管理的方式管理应用的状态。
使用步骤:
- 定义一个
reducer函数
(根据当前想要做的修改返回一个新的状态) - 使用
createStore方法
传入 reducer 函数, 生成一个 store 实例对象 - 使用
store 实例
的subscribe 方法
订阅数据的变化(数据一旦变化,可以得到通知) - 使用 store 实例的 dispatch 方法提交 action 对象 触发数据变化(告诉 reducer 怎么改数据)
- 使用 store 实例的 getState 方法 获取最新的状态数据更新到视图中
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/redux/4.0.0/redux.js"></script>
</head>
<body>
<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>
<script>
// 1. 定义reducer函数
// 作用:根据不同的action对象,返回不同的新的state
// state: 管理的数据初始状态
// action: 对象type标记当前想要做什么样的修改
function reducer(state = { count: 0 }, action) {
// 数据不可变:基于原生状态生成一个新的状态
if (action.type === 'INCREMENT') {
return { count: state.count + 1 }
}
if (action.type === 'DECREMENT') {
return { count: state.count - 1 }
}
return state
}
// 2. 使用reducer函数生成store实例
const store = Redux.createStore(reducer)
// 3. 通过store实例的subscribe订阅数据变化
// 回调函数可以在每次state发生变化的时候自动执行
store.subscribe(() => {
console.log('state变化了...', store.getState())
document.getElementById('count').innerHTML = store.getState().count
})
// 4. 通过store实例的dispatch函数提交action更改状态
const inBtn = document.getElementById('increment')
inBtn.addEventListener('click', () => {
store.dispatch({ type: 'INCREMENT' })
})
const dBtn = document.getElementById('decrement')
dBtn.addEventListener('click', () => {
store.dispatch({ type: 'DECREMENT' })
})
</script>
</body>
</html>
Redux 在 react 项目中的环境准备
在 React 中使用 redux,官方要求安装两个其他的插件 Redux Toolkit
、 react-redux
bash
npm i @reduxjs/toolkit react-redux
Redux Toolkit: 是官方推荐编写 Redux 逻辑的方式,是一套工具的集合,简化书写方法
- 简化 Store 的配置方式
- 内置 immer 支持可变式状态修改
- 内置 thunk 更好的异步创建
react-redux:用来 链接 Redux 和 React 组件的中间件
在 React 中使用 redux
1.使用 React Toolkit
创建 counterStore
jsx
import { createSlice } from '@reduxjs/toolkit'
const counterStore = createSlice({
name: 'counterStore'
initialState: {
count: 0
},
reducers: {
increment: state => {
state.count++
},
decrement: state => {
state.count--
}
}
})
const { increment, decrement } = counterStore.actions;
const counterReducer = counterStore.reducer;
export { increment, decrement };
export default counterReducer;
jsx
import { configureStore } from '@reduxjs/toolkit'
import counterStore from './modules/counterStore'
const store = configureStore({
reducer: {
counterStore: counterStore.reducer
}
})
export default store
2. 为 react 注入 store
react-redux 负责把 Redux 和 React 链接起来,内置 Provider 组件,通过 store 参数把创建好的 store 实例注入到应用中,链接正式建立
jsx
import store from './store'
import { Provider } from 'react-redux'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
)
3.React 组件中使用 store 中的数据
在 React 组件中使用 store 中的数据,需要用到一个钩子函数 useSelector
, 它的作用是把 store 中的数据映射到组件中
jsx
import { useSelector } from 'react-redux'
function ReduxExample() {
const { count } = useSelector((state) => state.counter)
return <div>{count}</div>
}
4.修改 store 中的数据
在 React 组件中修改 store 中的数据,需要用到一个 useDispatch
钩子函数,它的作用是返回一个函数,可以用来触发 store 中的 reducer 函数,修改数据
jsx
import { useSelector, useDispatch } from 'react-redux'
import { increment, decrement } from './store/modules/counterStore'
function ReduxExample() {
const { count } = useSelector((state) => state.counter)
const dispatch = useDispatch()
return (
<div>
<button onClick={() => dispatch(increment())}>-</button>
<span>{count}</span>
<button onClick={() => dispatch(decrement())}>+</button>
</div>
)
}