Redux 是一个用于管理 JavaScript 应用程序状态的可预测状态容器
整个应用的状态被存储在一个单一的对象树(store)中,这个对象树位于唯一的 store 里。
创建store:
const store = createStore(reducer)
唯一改变状态的方法是触发一个 action,action 是一个描述状态变化的纯对象。这保证了所有的状态变化都是可追踪的。
一个标准的 action
对象至少包含一个 type
属性,用于描述要执行的操作类型,除此之外,还可以携带额外的数据(通常命名为 payload
),用于传递与该操作相关的具体信息。其基本结构如下:
{
type: 'ACTION_TYPE',
// 可选的额外数据
payload: {
// 这里可以包含任意数量和类型的数据
key1: value1,
key2: value2
}
}
为了描述 action 如何改变状态树,需要编写 reducers。reducer 是一个纯函数,reducer 接收两个参数,当前的状态(state
)和一个 action 对象(action
),并返回一个新的状态。
// 定义初始状态
const initialState = {
todos: []
};
// 定义 reducer
const todoReducer = (state = initialState, action) => {
switch (action.type) {
case 'ADD_TODO':
return {
...state,
todos: [...state.todos, action.payload]
};
case 'DELETE_TODO':
return {
...state,
todos: state.todos.filter(todo => todo.id!== action.payload)
};
default:
return state;
}
};
// 测试 reducer
const addTodoAction = {
type: 'ADD_TODO',
payload: { id: 1, text: '学习 Redux' }
};
const newState = todoReducer(initialState, addTodoAction);
console.log(newState);
获取reducer中返回的state数据:
store.getState()
用于发送action,来修改reducer中的state数据:
store.dispatch()
用来注册监听state是否改变:
store.subscribe()
// 引入 redux
const { createStore } = require('redux');
// 定义 reducer
const counterReducer = (state = { counter: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return {
...state,
counter: state.counter + 1
};
case 'DECREMENT':
return {
...state,
counter: state.counter - 1
};
default:
return state;
}
};
// 创建 store
const store = createStore(counterReducer);
// 订阅状态变化
store.subscribe(() => {
console.log('当前状态:', store.getState());
});
// 发起 action
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' });
Redux 中间件可以在 action 被 dispatch 到 reducer 之前对其进行拦截和处理,常见的中间件有 redux-thunk
和 redux-promise
等,用于处理异步操作。例如使用 redux-thunk
处理异步请求:
const { createStore, applyMiddleware } = require('redux');
const thunk = require('redux-thunk').default;
// 异步 action 创建函数
const fetchData = () => {
return (dispatch) => {
dispatch({ type: 'FETCH_DATA_REQUEST' });
setTimeout(() => {
dispatch({ type: 'FETCH_DATA_SUCCESS', payload: 'Data fetched successfully' });
}, 1000);
};
};
// 定义 reducer
const dataReducer = (state = { loading: false, data: null }, action) => {
switch (action.type) {
case 'FETCH_DATA_REQUEST':
return {
...state,
loading: true
};
case 'FETCH_DATA_SUCCESS':
return {
...state,
loading: false,
data: action.payload
};
default:
return state;
}
};
// 创建 store 并应用中间件
const store = createStore(dataReducer, applyMiddleware(thunk));
// 发起异步 action
store.dispatch(fetchData());
通常使用 react-redux
库将 Redux 与 React 集成,它提供了 Provider
组件和 connect
函数(或 useSelector
和 useDispatch
Hooks)来连接 React 组件和 Redux store。示例如下:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';
// 定义 reducer
const counterReducer = (state = { counter: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return {
...state,
counter: state.counter + 1
};
case 'DECREMENT':
return {
...state,
counter: state.counter - 1
};
default:
return state;
}
};
// 创建 store
const store = createStore(counterReducer);
// 定义 React 组件
const Counter = () => {
const counter = useSelector((state) => state.counter);
const dispatch = useDispatch();
return (
计数器: {counter}
);
};
// 渲染应用
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
);