从redux中回复承诺

时间:2017-06-01 12:49:35

标签: reactjs react-redux

我是react-redux的新手,当时我有一个简单的页面登录到现有服务(调用正在工作,我从服务器获取数据),我想获取组件中的数据并设置设置cookie并根据从服务器接收的数据重定向用户。 我在动作中获取数据,但在组件中它是未定义的。 谢谢大家

表单组件中的submit函数:

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

还需要更多代码吗?

3 个答案:

答案 0 :(得分:2)

第一个问题是您的reducer代码。 它应该是这样的: -

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

接下来的问题是渲染函数内部。内部渲染功能,检查是否是你的 this.props.userProfile对象是否已定义,如果只是在登录成功时才会发生,则使用

将他/她重定向到/ homepage路由

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

答案 1 :(得分:1)

尽管代码可能正常工作,但上述所有内容肯定是一件麻烦事,但这种代码并不容易理解,因为你正在混淆" dirty"组件和操作中的异步代码。

我建议您使用redux-saga将副作用与组件和操作分开。

A good starting point here.

第1步:触发行动

第2步:抓住" saga"而不是减速器:

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步:如果你有更多"脏"代码,只需在saga内部运行(例如重定向)

答案 2 :(得分:0)

你能检查一下你是否用redux连接表单组件?如果是,您应该直接通过this.props而不是this.props.actions.loginUser访问该操作。也许这不是问题,因为我没有机会查找表单组件的完整代码。

希望这有帮助。