<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>
<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>
<script>
// 定义reducer函数
// 内部主要的工作是根据不同的action 返回不同的state
function counterReducer (state = { count: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 }
case 'DECREMENT':
return { count: state.count - 1 }
default:
return state
}
}
// 使用reducer函数生成store实例
const store = Redux.createStore(counterReducer)
// 订阅数据变化
store.subscribe(() => {
console.log(store.getState())
document.getElementById('count').innerText = store.getState().count
})
// 增
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>
Redux详解
Redux是一个用于JavaScript应用的状态管理库,它提供了一种可预测化的状态管理方式,特别适用于单页应用(SPA)。Redux通过将整个应用的状态存储在一个单一的对象(即“状态树”)中,使得状态管理变得更加集中和可控。
Redux的核心概念
- Store:存储应用的状态树和分发动作(action)的对象。
- State:存储在Store中的数据对象,它描述了应用在某个时刻的状态。
- Action:描述要发生什么的普通对象,必须包含一个
type
属性,用于指示要执行的动作类型。 - Reducer:纯函数,接收当前状态和动作,返回新的状态。Reducer负责根据动作来更新状态。
Redux的工作流程
- 组件通过调用
store.dispatch
方法派发一个action。 - Store接收到action后,将其传递给reducer。
- Reducer根据action的
type
属性和当前状态,计算出新的状态,并返回给Store。 - Store将新的状态保存到状态树中,并通知所有订阅了状态变化的组件。
- 组件根据新的状态重新渲染。
Redux示例
以下是一个简单的Redux计数器应用的示例,包括Action、Reducer、Store和React组件的连接。
- 定义Action
// actions.js
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
export const increment = () => ({ type: INCREMENT });
export const decrement = () => ({ type: DECREMENT });
- 定义Reducer
// reducer.js
const initialState = { count: 0 };
const counterReducer = (state = initialState, action) => {
switch (action.type) {
case INCREMENT:
return { ...state, count: state.count + 1 };
case DECREMENT:
return { ...state, count: state.count - 1 };
default:
return state;
}
};
export default counterReducer;
- 创建Store
// store.js
import { createStore } from 'redux';
import counterReducer from './reducer';
const store = createStore(counterReducer);
export default store;
- 连接React组件
使用react-redux
库中的Provider
和connect
函数将Redux Store连接到React组件中。
// App.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider, useSelector, useDispatch } from 'react-redux';
import store from './store';
import { increment, decrement } from './actions';
const Counter = () => {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<div>
<h1>{count}</h1>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</div>
);
};
const App = () => (
<Provider store={store}>
<Counter />
</Provider>
);
ReactDOM.render(<App />, document.getElementById('root'));
图解
由于直接在这里绘制图解不太现实,但我可以描述一个简化的Redux数据流图:
- 组件:表示React组件,它们通过
useSelector
钩子从Store中读取状态,并通过useDispatch
钩子派发action。- Store:表示Redux Store,它存储了应用的状态树,并接收来自组件的action。
- Reducer:表示Reducer函数,它根据action和当前状态计算出新的状态,并返回给Store。
- 数据流:
- 组件派发action给Store。
- Store将action传递给Reducer。
- Reducer计算新的状态并返回给Store。
- Store更新状态树,并通知所有订阅了状态变化的组件。
- 组件根据新的状态重新渲染。
通过这个流程,Redux确保了应用状态的可预测性和可控性。
异步