2017-06-01 17 views
1

我是react-redux中的新人,當時我有一個簡單的頁面來登錄現有服務(調用正在工作,我從服務器獲取數據),我想要獲取組件中的數據並設置設置cookie,並根據從服務器接收的數據重定向用戶。 我在操作中獲取數據,但在組件中未定義。 謝謝大家返回從諾言中的行動

在表單組件的提交功能:

onSubmit(e) { 
     e.preventDefault(); 
     if (this.isValid()) { 
      this.setState({ errors: {}, isLoading: true }); 
      this.props.actions.loginUser(this.state).then(
       function (res) { 
        this.context.router.push('/'); 
       }, 
       function (err) { 
        this.setState({ errors: err.response.data.errors, isLoading: false }); 
       } 
      ); 
     } 
    } 

的操作功能:

import * as types from './actionTypes'; 
import loginApi from '../api/loginApi'; 

export function loginSuccess(result) { 
    return { type: types.LOGIN_SUCCESS, result }; 
} 

export function loginFailed(result) { 
    return { type: types.LOGIN_FAILURE, result }; 
} 

export function loginUser(data) { 
    return dispatch => { 
     return loginApi.loginUser(data).then(result => { 
      if (result) { 
       if (result.ErrorCode == 0) 
        dispatch(loginSuccess(result)); 
       else 
        dispatch(loginFailed(result)); 
      } 
     }).catch(error => { 
      throw (error); 
     }); 
    }; 
} 

的API:

static loginUser(data) { 
    return fetch(API + "/SystemLogin.aspx", 
     { 
     method: 'POST', 
     mode: 'cors', 
     body: JSON.stringify({ 
      User: data.identifier, 
      Password: data.password 
     }) 
     }).then(function (response) { 
     return response.json(); 
     }) 
     .then(function (parsedData) { 
     return parsedData; 
     //resolve(parsedData); 
     }) 
     .catch(error => { 
     return error; 
     }); 
    } 

減速機:

import * as types from '../actions/actionTypes'; 
import LoginApi from '../api/loginApi'; 
import initialState from './initialState'; 

export default function loginReducer(state = initialState.login, action) { 
    switch (action.type) { 
     case types.LOGIN_SUCCESS: 
     return [...state, Object.assign({}, action.courses)]; 
      //return action.result; 
     case types.LOGIN_FAILURE: 
      return action.result; 
     default: 
      return state; 
    } 
} 

是否還需要其他代碼?

回答

2

第一個問題是你減速的代碼。 它應該是這樣的: -

import * as types from '../actions/actionTypes'; 
import LoginApi from '../api/loginApi'; 
import initialState from './initialState'; 

export default function loginReducer(state = initialState.login, action) { 
    switch (action.type) { 
     case types.LOGIN_SUCCESS: 
     return Object.assign({}, state, { userProfile: action.results }); 
      //return action.result; 
     case types.LOGIN_FAILURE: 
      return action.result; 
     default: 
      return state; 
    } 
} 

的第二個問題是你想給用戶發送到另一個路由的方式。 它應該是這樣的: -

onSubmit(e) { 
     e.preventDefault(); 
     if (this.isValid()) { 
      this.setState({ errors: {}, isLoading: true }); 
      this.props.actions.loginUser(this.state); 
     } 
    } 

下一個問題是內部的渲染function.Inside渲染功能,把支票是你 this.props.userProfile對象被定義或沒有,如果它是隻會發生在登錄成功,那麼他/她重定向到使用

this.context.router.push("/homepage");

1

雖然代碼可能正在工作,但做上述所有操作確實是一件麻煩的事情,因爲您在組件和操作中混合使用「髒」異步代碼,所以代碼不易於以這種方式理解。

我建議您使用redux-saga來區分組件和操作的副作用。

A good starting point here.

步驟1:觸發一個動作

步驟2:捕捉動作的 「傳奇」,而不是一個減速器內:

import { put, takeEvery, all } from 'redux-saga/effects' 

// Our worker Saga: will perform the async increment task 
export function* loginUserAsync() { 
    yield put({ type: 'LOGIN_SUCCESS' }) 
} 

// Our watcher Saga: spawn a new loginUserAsync task on each LOGIN_USER 
export function* watchIncrementAsync() { 
    yield takeEvery('LOGIN_USER', loginUserAsync) 
} 

步驟3:後觸發一個新的動作異步代碼已完成並在Reducer內部捕獲以更新狀態。

第4步:如果你有更多的「髒」的代碼,只需將裏面的傳奇運行(重定向例如)

+2

他已經在使用redux thunk我猜。佐賀會服務於相同的目的 – VivekN

+0

嗨艾哈邁德,首先感謝您的重播,第二是使用傳奇是可以爲REDX?因爲我是新的反應,我試圖留在編寫代碼的最佳做法。我會閱讀關於這個傳奇故事並嘗試實施它。 – Danny

+1

@Danny sagas在redux中使用來解決「副作用」問題,並擺脫像你所面對的問題,使用thunk是好的,但它仍然保持「髒代碼」混合在一起,我們已經一直在生產中使用傳奇一段時間,它的相當了不起,它值得嘗試,因爲你剛剛開始 – Bamieh

0

你能確認你的表單組件與終極版連接/主頁的路由?如果是的話,你應該直接通過this.props來訪問action,而不是this.props.actions.loginUser。也許這不是問題,因爲我沒有機會查找表單組件的完整代碼。

希望這會有所幫助。

+0

沒有抱歉,這不是問題 – Danny