2017-09-29 31 views
0

Ich implementiere Login-Seite mit reaktiven nativen und redux. Hier ist mein Beispielcode für meinen Reduzierer. Es gibt drei Arten; types.SUBMIT_LOGIN, types.CHANGE_USERNAME, types.CHANGE_PASSWORD.Zustand wird nicht geändert mit react redux

CHANGE_USERNAME und CHANGE_PASSWORD funktioniert gut. Aber das Problem ist SUBMIT_LOGIN.Ich denke, es liegt an asynchronen Statusänderungen. Gibt es da eh den Zustand nach der fetch() Methode zu ändern ??

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; 

} }

Antwort

1

Sie sollten mit Asynchron-Anruf innerhalb Minderer vermeiden. Sie sollten eine separate Methode haben, die einen asynchronen Anruf ausführt, und wenn dieser Anruf beendet ist, sendet sie eine Aktion (in Ihrem Fall SUBMIT_LOGIN) entsprechend.

eine separate Funktion Halten und Versand eine Aktion, wenn Anfrage wie dieser

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 }}) 
     }) 
} 

abgeschlossen ist, und halten Sie Ihre Minderer sauber. Es sollte einen neuen Zustand zurück nach 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

Ich glaube, Sie dies durch den Einsatz Thunk Middleware erreichen können:

https://github.com/gaearon/redux-thunk.

Mit diesem Befehl können Sie einen asynchronen Aktionsersteller erstellen, der schließlich eine Aktion zur Aktualisierung des Status sendet. Wenn Sie die Aktion erstellen, bevor Sie sie in den Reducer geben, sollten Sie das Problem umgehen, das Sie hier haben.

Zuerst werden Sie eine einfache Aktion

const submitLogin(loginStatus, errorMessage){ 
    return { 
    type: SUBMIT_LOGIN, 
    loginStatus, 
    errorMessage 
    } 
} 

Dann definieren Sie die Asynchron-Aktion erstellen werden, die schließlich die Aktion versenden wird, in den Ergebnissen Ihrer als Argumente holen vorbei

const thunk =()=>{ 
    return (dispatch, getState)=> { 
    <async action goes here> 
    dispatch(submitLogin(loginStatus, errorMessage)); 
    } 
} 

Sie können dann eine viel einfachere Aktion in Ihrem Reduzierer erstellen, die den Status basierend auf der einfachen Aktion aktualisiert, die Sie eingeben. Sie sollten den Thunk-Aktionsersteller dort importieren, wo Sie ihn in Ihrem Code verwenden.

Verwandte Themen