Redux 登录
Redux logging in
我一直在寻找一种优雅(且正确)的方式来处理 Redux 应用程序的登录。当前,用户被定向到登录 component/container,他在其中看到带有用户名和密码的表单。然后,当他点击提交时,我会调用一个异步登录函数,当承诺得到满足时,我会发送一个 loginSuccess 和一个 replacePath 调用。以下是一些伪代码:
submit(e) {
login(username, password)
.then(function (user) {
dispatch(loginSuccess(user));
dispatch(replacePath('/');
});
}
这可行,但我不确定这是最佳做法。谁有更好的实现方式?
在组件内调用调度通常被认为是不好的做法,除非它是一个连接到商店的 top-level 容器。
我建议遵循 Dan Abramov 在文档中提供的示例,尤其是 async Reddit post fetching example。看看他是如何处理posts.isFetching
.
请求的中间过程的
因为我知道 Whosebug 不喜欢链接,这里有一个简化的例子(在 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 调用带有身份验证结果的后端 returns ,您将发送 authSuccess() 或 authFail() 来更新状态并通知用户他们的请求是否成功。
我一直在寻找一种优雅(且正确)的方式来处理 Redux 应用程序的登录。当前,用户被定向到登录 component/container,他在其中看到带有用户名和密码的表单。然后,当他点击提交时,我会调用一个异步登录函数,当承诺得到满足时,我会发送一个 loginSuccess 和一个 replacePath 调用。以下是一些伪代码:
submit(e) {
login(username, password)
.then(function (user) {
dispatch(loginSuccess(user));
dispatch(replacePath('/');
});
}
这可行,但我不确定这是最佳做法。谁有更好的实现方式?
在组件内调用调度通常被认为是不好的做法,除非它是一个连接到商店的 top-level 容器。
我建议遵循 Dan Abramov 在文档中提供的示例,尤其是 async Reddit post fetching example。看看他是如何处理posts.isFetching
.
因为我知道 Whosebug 不喜欢链接,这里有一个简化的例子(在 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 调用带有身份验证结果的后端 returns ,您将发送 authSuccess() 或 authFail() 来更新状态并通知用户他们的请求是否成功。