2017-09-29 42 views
0

我正在实施登录页面使用反应本机和REDX。这是我的减速器的示例代码。有三种类型;类型.SUBMIT_LOGIN,类型.CHANGE_USERNAME,类型.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; 

}}

回答

1

您应该避免使用减速机里面的异步调用。你应该有一个独立的方法来做异步调用,当这个调用完成时,它会相应地发送一个动作(你的情况为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; 
2

返回一个新的状态,我相信你可以通过使用咚中间件实现这一目标:

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动作创建器。