通常认为在组件内调用 dispatch 是不好的做法,除非它是连接到 store 的顶级容器。
我建议遵循 Dan Abramov 在文档中提供的示例,最值得注意的是async Reddit post fetching example。看看他是如何处理临时请求的posts.isFetching
。
因为我知道 StackOverflow 不喜欢链接,所以这是一个简化的示例(在 ES6 中):
这些是行动:
// Actions
import fetch from 'isomorphic-fetch';
import * as types from '../constants/actionTypes.js';
var requestAuth = function() {
return {
type: type.REQUEST_AUTH
}
};
var authSuccess = function(response) {
return {
type: type.AUTH_SUCCESS,
response: response
}
};
var authFail = function(response) {
return {
type: type.AUTH_FAIL,
response: response
}
};
var authenticate = function(username, password) {
var fetchOptions = {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({username: username, password: password})
};
var uri = '/api/path/to/your/login/backend';
return dispatch => {
dispatch(requestAuth);
return fetch(uri, fetchOptions)
.then(response => {
if (resopnse.status === 200) {
dispatch(authSuccess(response));
// Do any other login success work here
// like redirecting the user
} else {
dispatch(authFail(response));
}
}
}
};
接下来是减速机:
// Reducer
import { combineReducers } from 'redux';
import { REQUEST_AUTH, AUTH_SUCCESS, AUTH_FAIL } from '../actions/login';
function login(state = {
isAuthenticating: false,
isLoggedIn: false,
authenticationToken: '',
authError: null
....., // whatever other state vars you need
.....
}, action) {
switch(action.type) {
case REQUEST_AUTH:
return Object.assign({}, state, {
isAuthenticating: true
});
break;
case AUTH_SUCCESS:
return Object.assign({}, state, {
isAuthenticating: false,
isLoggedIn: true,
authenticationToken: action.response.token
});
break;
case AUTH_FAIL:
return Object.assign({}, state, {
isAuthenticating: false,
authError: action.response.error
});
break;
default:
return state;
}
}
最后是组件方法
// Component Method
// authenticate() should be wrapped in bindActionCreators()
// and passed down as a prop
function handleSubmit(username, password) {
if (isValid(username) && isValid(password) {
authenticate(username, password);
}
}
tl;dr 您的用户输入他们的凭据,这应该是状态的一部分(此处未显示)。组件中的onClick 调用handleSubmit(),它调度authenticate()。Authenticate 调度 requestAuth() 更新状态以向您的用户显示正在处理请求(显示加载微调器或其他内容)。一旦您对后端的 AJAX 调用返回了身份验证结果,您就会分派 authSuccess() 或 authFail() 来更新状态并通知用户他们的请求是否成功。