0%

Redux 食用指南

Redux 是一个强大的状态管理框架,被广泛用于管理应用程序的状态。它的设计理念是让状态的更新可预测和透明。本文将简要探讨 Redux 的核心机制和实际应用。

在 Redux 中,有一个状态对象负责应用程序的整个状态.Redux store 是应用程序状态的唯一真实来源

如果应用程序想要更新状态,只能通过 Redux store 执行,单向数据流可以更轻松地对应用程序中的状态进行监测管理。

Redux store 是一个保存和管理应用程序状态的 state,使用 Redux 对象中的 createStore() 来创建一个 redux store,此方法将 reducer 函数作为必需参数.

1
2
3
const reducer = (state = 5) => state;

const store = Redux.createStore(reducer);

获取数据

Redux store 对象提供了几种允许你与之交互的方法,可以使用 getState() 方法检索 Redux store 对象中保存的当前的 state

1
2
3
4
5
6
const store = Redux.createStore(
(state = 5) => state
);

// 更改此行下方的代码
const currentState = store.getState();

更新状态

由于 Redux 是一个状态管理框架,因此更新状态是其核心任务之一。在 Redux 中,所有状态更新都由 dispatch action 触发,action 只是一个 JavaScript 对象,其中包含有关已发生的 action 事件的信息。

Redux store 接收这些 action 对象,然后更新相应的状态。action 对象中必须要带有 type 属性,reducer 才能根据 type 进行区分处理。
action 除了 type 属性外,还可以附带数据给 reducer 做相应的处理,这个数据是可选的。

我们可以将 Redux action 视为信使,将有关应用程序中发生的事件信息提供给 Redux store,然后 store 根据发生的 action 进行状态的更新。

reducer

reducer 将 state 和 action 作为参数,并且它总是返回一个新的 state。这是 reducer 的唯一的作用,它不应有任何其他的作用。比如它不应调用 API 接口,也不应存在任何潜在的副作用。reducer 只是一个接受状态和动作,然后返回新状态的纯函数

在 reducer 中一般通过 switch 进行判断 action 的类型,做不同的处理。

订阅事件

store.subscribe() 可以订阅 store 的数据变化,它接收一个回调函数作为参数。当 store 数据更新时会调用该回调函数。

模块划分

当应用程序的状态开始变得越来越复杂时,将状态划分为多个部分可能是个更好的选择。我们可以考虑将不同的模块进行划分,Login 作为一个模块,Account 作为另一个模块。

但对 state 进行模块划分也不能破坏 redux 中将数据存入简单 state 的原则。因此可以生成多个 reducer, 再将它们合并到 root reducer 中。

redux 提供了 combineReducers() 函数对 reducer 进行合并。它接收一个对象作为参数,对象中的 key/value 别分对应着 module name 和相对应的 reducer 函数。

1
2
3
4
5
6
7

const rootReducer = Redux.combineReducers({
counter: counterReducer,
auth: authReducer
})

const store = Redux.createStore(rootReducer);

异步

redux 本身是不能直接处理异步操作,因此需要引入中间件来处理这些问题。在 createStore 时,还可以传入第二个可选参数,这个参数就是传递给 redux 的中间件函数。

Redux 提供了 applyMiddleware() 来创建一个中间件,一般处理 redux 异步的中间件有 redux-thunkredux-saga 等。

redux-thunk

redux-thunk 允许 action 创建函数返回一个函数而不是一个 action 对象。这个返回的函数接收 dispatchgetState 作为参数,允许直接进行异步操作和状态的分发。

例如,一个异步获取数据的 thunk 可能如下所示:

1
2
3
4
5
6
7
8
9
function fetchData() {
return (dispatch, getState) => {
// 异步操作
fetch('some-api-url')
.then(response => response.json())
.then(data => dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data }))
.catch(error => dispatch({ type: 'FETCH_DATA_ERROR', error }));
};
}

redux-saga

redux-saga 是一个更高级的中间件,它使用 ES6 的 Generator 函数来让你以同步的方式写异步代码。saga 监听发起的 action,并决定基于这些 action 执行哪些副作用(如异步获取数据、访问浏览器缓存等)。

一个简单的 saga 可能如下所示:

1
2
3
4
5
6
7
8
function* fetchDataSaga(action) {
try {
const data = yield call(fetch, 'some-api-url');
yield put({ type: 'FETCH_DATA_SUCCESS', payload: data });
} catch (error) {
yield put({ type: 'FETCH_DATA_ERROR', error });
}
}

React 与 Redux

在 React 应用中,Redux 被用来跨组件共享状态。使用 react-redux 库可以方便地将 Redux 集成到 React 应用中。

Provider 组件

Providerreact-redux 提供的一个组件,它使 Redux store 对 React 应用中的所有组件可用。通常,我们在应用的最顶层包裹 Provider 并传入 store:

1
2
3
4
5
6
7
8
import { Provider } from 'react-redux';
import { store } from './store';

const App = () => (
<Provider store={store}>
<MyRootComponent />
</Provider>
);

connect 函数

connect 是一个高阶函数,用于将 React 组件连接到 Redux store。它接受两个参数:mapStateToPropsmapDispatchToProps,分别用于从 store 中读取状态和向 store 发起 actions。

1
2
3
4
5
6
7
8
9
10
11
import { connect } from 'react-redux';

const mapStateToProps = state => ({
items: state.items
});

const mapDispatchToProps = dispatch => ({
fetchData: () => dispatch(fetchData())
});

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

总结

Redux 提供了一种统一、可预测的方式来管理应用程序的状态。通过使用 actions, reducers 和 store,开发者可以以一种高度解耦的方式来管理状态和 UI。

当结合异步处理和 React 集成时,Redux 成为了一个强大的工具,能够提升大型应用程序的开发和维护效率。

「请笔者喝杯奶茶鼓励一下」

欢迎关注我的其它发布渠道