Redux 本身是不支持异步操作的,但是可以通过中间件来实现异步任务。最常用的中间件就是 redux-thunk 和 redux-saga。
- redux-thunk:
redux-thunk 中间件允许你写 action creator 返回函数而不是 action。这个函数会由 redux-thunk 中间件执行,并且会接受 dispatch 和 getState 作为参数。
以下是一个使用 redux-thunk 进行异步操作的示例:
首先,安装 redux-thunk:
npm install --save redux-thunk
然后,在创建 store 时应用中间件:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const store = createStore(rootReducer, applyMiddleware(thunk));
接下来,编写一个返回函数的 action creator 来处理异步操作:
const fetchPosts = () => {
return dispatch => {
dispatch({ type: 'FETCH_POSTS_REQUEST' });
axios.get('/posts')
.then(response => {
dispatch({ type: 'FETCH_POSTS_SUCCESS', payload: response.data });
})
.catch(error => {
dispatch({ type: 'FETCH_POSTS_FAILURE', payload: error.message });
});
};
};
最后,在组件中分发该操作:
import { fetchPosts } from './actions';
// ...
const mapDispatchToProps = dispatch => ({
fetchPosts: () => dispatch(fetchPosts())
});
export default connect(null, mapDispatchToProps)(MyComponent);
- redux-saga:
redux-saga 是一个更强大的中间件,它使用 ES6 生成器函数来管理异步操作。redux-saga 的主要优势在于它可以很容易地管理副作用并保持 action 和 reducer 纯净。
以下是一个使用 redux-saga 进行异步操作的示例:
首先,安装 redux-saga:
npm install --save redux-saga
然后,在创建 store 时应用中间件:
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(rootSaga);
接下来,编写一个 saga 来处理异步操作:
import { takeEvery, put } from 'redux-saga/effects';
import axios from 'axios';
function* fetchPosts() {
try {
yield put({ type: 'FETCH_POSTS_REQUEST' });
const response = yield axios.get('/posts');
yield put({ type: 'FETCH_POSTS_SUCCESS', payload: response.data });
} catch (error) {
yield put({ type: 'FETCH_POSTS_FAILURE', payload: error.message });
}
}
function* watchFetchPosts() {
yield takeEvery('FETCH_POSTS', fetchPosts);
}
export default function* rootSaga() {
yield [
watchFetchPosts(),
// ...
];
}
最后,在组件中分发一个普通的同步操作:
import { FETCH_POSTS } from './constants';
// ...
const mapDispatchToProps = dispatch => ({
fetchPosts: () => dispatch({ type: FETCH_POSTS }),
});
export default connect(null, mapDispatchToProps)(MyComponent);