2017-06-01 76 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