异步操作在 Redux 中的问题
在使用 Redux 进行状态管理时,我们通常会遇到需要进行异步操作的情况。比如:从服务器获取数据、处理用户输入、将数据保存到服务器等等。Redux 官方推荐的做法是只在 reducer 中进行同步操作,而异步操作则移到其他地方去,例如 componentDidMount
生命周期中。
然而,这种方法也有一些缺点。比如:每个需要进行异步操作的组件都需要编写相关代码;这些操作通常被写成了不同的函数,让代码的组织变得混乱。Redux 本身并不支持异步操作,这让开发者需要更多的代码去实现异步操作。
Thunk 的介绍
为了解决这些问题,Redux 社区提出了一个解决方案:使用 Redux Thunk。Thunk 是一个函数,它允许我们返回一个新的函数,而这个新函数可以在 Redux store 中被调用。这个新函数就是一个 thunk。
Thunk 允许我们在 store 中进行异步操作,而不需要编写过多的代码。通过 thunk,我们可以使用 store.dispatch 方法,来发出一个异步操作请求,而这个请求可以被 store 中的中间件进行拦截和处理。相比起其他解决方案,Thunk 代码更简洁,易于维护,并且可重用性更高。
使用 Thunk 进行异步操作的示例
为了展示 Thunk 的使用,我们以一个 TodoList 应用为例。以下是我们的代码:
// javascriptcn.com 代码示例 import { createStore, applyMiddleware } from 'redux'; import thunkMiddleware from 'redux-thunk'; const initialState = { todos: [], loading: false }; function reducer(state = initialState, action) { switch (action.type) { case 'ADD_TODO': return { ...state, todos: [...state.todos, action.payload] }; case 'FETCH_TODOS_START': return { ...state, loading: true }; case 'RECEIVE_TODOS': return { ...state, loading: false, todos: action.payload }; default: return state; } } function fetchTodos() { return function(dispatch) { dispatch({ type: 'FETCH_TODOS_START' }); fetch('https://my.api.com/todos').then((response) => { response.json().then((json) => { dispatch({ type: 'RECEIVE_TODOS', payload: json }); }); }); } } const store = createStore(reducer, applyMiddleware(thunkMiddleware)); store.dispatch(fetchTodos());
在上面的代码中,我们首先创建了一个名为 reducer
的 reducer 函数,它会根据 action 中的 type
字段,来决定如何更新 state。然后,我们定义了一个 fetchTodos
函数,它返回一个 thunk 函数。这个 thunk 函数首先会 dispatch 一个 FETCH_TODOS_START
action,然后发起一个异步请求,获取 todo list 数据,并在数据返回后 dispatch 一个 RECEIVE_TODOS
action,将数据保存到 state 中。
最后,我们通过使用 Thunk 中间件将 store 增强,然后发出一个 fetchTodos
action,来触发我们的异步操作。
总结
本教程介绍了使用 Thunk 在 Redux 中进行异步操作的方法,并给出了一个示例代码。相比于其他解决方案,Thunk 代码更简洁易懂,并且可重用性更高。如果你想更好地管理 Redux 中的异步操作,那就试试使用 Thunk 吧。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653a55007d4982a6eb447513