我正在使用react native和redux实现登录页面。这是我的reducer的示例代码。有三种类型; types.SUBMIT_LOGIN,types.CHANGE_USERNAME,types.CHANGE_PASSWORD。
CHANGE_USERNAME和CHANGE_PASSWORD工作正常。但问题是SUBMIT_LOGIN。我猜它是因为异步状态的变化。无论如何在那里使用fetch()方法改变状态??
export default function login(state = initialState, action = {}) {
switch (action.type) {
case types.SUBMIT_LOGIN: {
let loginStatus = false;
if (state.username != null && state.password != null
&& state.username.length > 0 && state.password.length > 0
&& state.username === state.password) {
loginStatus = true;
} else {
let updatedErrMsg = '';
fetch('https://staging-barrie.mpower.ca/mpower/mpp/weblogin2.action?username='+state.username+'&password='+state.password,
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
},
}
)
.then((response) => response.json())
.then((responseJson) => {
if (responseJson.result === 'success') {
loginStatus = true;
} else {
loginStatus = false;
updatedErrMsg = 'Incorrect Username or Password.';
}
return {
...state,
isLoggedIn: loginStatus,
errorMsg: updatedErrMsg
};
});
}
return {
...state,
isLoggedIn: loginStatus
};
}
case types.CHANGE_USERNAME:
return {
...state,
username: action.username
};
case types.CHANGE_PASSWORD:
return {
...state,
password: action.password
};
default:
return state;
} }
答案 0 :(得分:2)
我相信您可以通过使用Thunk中间件来实现这一目标:
https://github.com/gaearon/redux-thunk
使用此功能,您可以创建一个异步操作创建器,最终将调度操作以更新状态。通过在将其送入减速器之前创建动作,您应该规避您在此处遇到的任何问题。
首先,您要定义一个简单的操作
const submitLogin(loginStatus, errorMessage){
return {
type: SUBMIT_LOGIN,
loginStatus,
errorMessage
}
}
然后,您将创建异步操作,最终将调度该操作,并将获取的结果作为参数传递
const thunk = ()=>{
return (dispatch, getState)=> {
<async action goes here>
dispatch(submitLogin(loginStatus, errorMessage));
}
}
然后,您可以在reducer中构建一个更简单的操作,根据您提供的简单操作更新状态。您将要在您的代码中的任何位置导入thunk action creator
答案 1 :(得分:1)
你应该避免在reducer中使用异步调用。您应该有一个单独的方法来执行异步调用,并且当该调用完成时,它将相应地调度一个操作(在您的情况下为SUBMIT_LOGIN
)。
保留单独的功能,并在请求完成时发送操作,如此
function loginUser () {
let loginStatus = false;
if (state.username != null && state.password != null
&& state.username.length > 0 && state.password.length > 0
&& state.username === state.password) {
loginStatus = true;
} else {
let updatedErrMsg = '';
fetch('https://staging-barrie.mpower.ca/mpower/mpp/weblogin2.action?username='+state.username+'&password='+state.password,
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
},
}
)
.then((response) => response.json())
.then((responseJson) => {
if (responseJson.result === 'success') {
loginStatus = true;
} else {
loginStatus = false;
updatedErrMsg = 'Incorrect Username or Password.';
}
// Request is complete so dispatch an action.
dispactch({type: types.SUBMIT_LOGIN, payload: {loginStatus,updatedErrMsg }})
})
}
保持你的减速机清洁。它应该根据action.type
export default function login(state = initialState, action = {}) {
switch (action.type) {
case types.SUBMIT_LOGIN:
return {
...state,
isLoggedIn: action.payload.loginStatus,
errorMsg: action.paylod.updatedErrMsg
};
case types.CHANGE_USERNAME:
return {
...state,
username: action.username
};
case types.CHANGE_PASSWORD:
return {
...state,
password: action.password
};
default:
return state;