我刚刚开始熟悉redux
和redux-thunk
,我尝试了下面的代码片段来处理async
调用,使用redux
和redux-thunk
。
const redux = require('redux');
const thunk = require('redux-thunk').default;
const axios = require('axios');
const createStore = redux.createStore;
const applyMiddleware = redux.applyMiddleware;
const accessPoint = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com/',
responseType: 'json',
headers: {
'Accept-Encoding': '',
},
});
const FETCH_USER_PENDING = 'FETCH_USER_PENDING';
const FETCH_USER_FULFILLED = 'FETCH_USER_FULFILLED';
const FETCH_USER_REJECTED = 'FETCH_USER_REJECTED';
const initialState = {
isLoading: false,
users: [],
error: '',
}
const fetchUserPending = () => {
return {type: FETCH_USER_PENDING}
}
const fetchUserFulfilled = data => {
return {type: FETCH_USER_FULFILLED, payload: data}
}
const fetchUserRejected = errorMessage => {
return {type: FETCH_USER_REJECTED, payload: errorMessage}
}
const reducer = (state = initialState, action) => {
const {type, payload} = action;
switch(type){
case FETCH_USER_PENDING: {
return {
...state,
isLoading: true,
}
}
case FETCH_USER_FULFILLED: {
return {
isLoading: false,
users: payload,
error: ''
}
}
case FETCH_USER_REJECTED: {
return {
isLoading: false,
users: [],
error: payload
}
}
default: return state;
}
}
const fetchUsers = () => {
return function(dispatch){
dispatch(fetchUserPending());
accessPoint.get('users')
.then(response => {
dispatch(fetchUserFulfilled(response.data.map(user => user.name)))
})
.catch(error => {
dispatch(fetchUserRejected(error.message));
})
}
}
const store = createStore(reducer, applyMiddleware(thunk));
store.subscribe(() => {
console.log(store.getState());
})
store.dispatch(fetchUsers());
Code On CodeSandBox
这绝对可以正常工作,并提供预期的输出。
还尝试了相同的示例,但没有thunk
和一些更改,
const redux = require('redux');
const axios = require('axios');
const createStore = redux.createStore;
const accessPoint = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com/',
responseType: 'json',
headers: {
'Accept-Encoding': '',
},
});
const FETCH_USER_PENDING = 'FETCH_USER_PENDING';
const FETCH_USER_FULFILLED = 'FETCH_USER_FULFILLED';
const FETCH_USER_REJECTED = 'FETCH_USER_REJECTED';
const initialState = {
isLoading: false,
users: [],
error: '',
}
const fetchUserPending = () => {
return {type: FETCH_USER_PENDING}
}
const fetchUserFulfilled = data => {
return {type: FETCH_USER_FULFILLED, payload: data}
}
const fetchUserRejected = errorMessage => {
return {type: FETCH_USER_REJECTED, payload: errorMessage}
}
const reducer = (state = initialState, action) => {
const {type, payload} = action;
switch(type){
case FETCH_USER_PENDING: {
return {
...state,
isLoading: true,
}
}
case FETCH_USER_FULFILLED: {
return {
isLoading: false,
users: payload,
error: ''
}
}
case FETCH_USER_REJECTED: {
return {
isLoading: false,
users: [],
error: payload
}
}
default: return state;
}
}
const fetchUsers = (dispatch) => {
dispatch(fetchUserPending());
accessPoint.get('users')
.then(response => {
dispatch(fetchUserFulfilled(response.data.map(user => user.name)))
})
.catch(error => {
dispatch(fetchUserRejected(error.message));
})
}
const store = createStore(reducer);
store.subscribe(() => {
console.log(store.getState());
})
fetchUsers(store.dispatch);
Code On CodeSandBox
这里我没有用react-thunk
将函数传递给store.dispatch()
,而是将store.dispatch
传递给fetchUsers()
函数,并且根据阶段的不同,我会向它分派动作。
当两个代码段(一个使用redux-thunk
,另一个不使用)产生完全相同的输出时(不是总体差异,而是在上述场景中),redux-thunk
会给异步调用带来混乱。
如果在实践这些代码时出现了问题,请改正。
提前感谢您的意见。
1条答案
按热度按时间8ulbf1ek1#
Redux中间件系统和
redux-thunk
中间件提供了一种以简洁的方式表达异步动作的方法。1.你不需要每次调用action creator时都传递
store.dispatch
和store.getState
,ReduxapplyMiddleware
API会为你做这件事。1.您还可以使用
redux-thunk
的withExtraArgument()
API将配置值注入Thunks