Redux Saga似乎正在进行未知的API调用?

时间:2019-04-11 23:05:47

标签: reactjs redux react-redux redux-saga antd

我有一个登录表单(由Ant Design的Form构建)。这一切都与Redux Saga挂钩。在这个Saga中,我正在进行API调用,并且似乎一切正常,但是神秘地,当我使用put分派任何其他操作时,似乎还有一个额外的神秘API调用失败了,因为它没有从中读取正确填写表格。

我的表格:

import React from 'react';
import { connect } from 'react-redux';
import { Form, Icon, Input, Button } from 'antd';
import { FormComponentProps } from 'antd/lib/form';

import { loginRequest, ICredentials } from '../redux/auth';
import { FormContainer, LoginContainer } from './styles';

type Props = {
  login: (data: ICredentials) => {};
}

class LoginForm extends React.Component<Props & FormComponentProps> {
  handleSubmit = (e: React.SyntheticEvent) => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        this.props.login(values)
      }
    });
  }

  render() {
    const { getFieldDecorator } = this.props.form;
    return (
      <FormContainer>
        <Form className="login-form">
          <Form.Item>
            {getFieldDecorator('username', {
              rules: [{ required: true, message: 'Please input your username!' }],
            })(
              <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="Username" />
            )}
          </Form.Item>
          <Form.Item>
            {getFieldDecorator('password', {
              rules: [{ required: true, message: 'Please input your Password!' }],
            })(
              <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Password" />
            )}
          </Form.Item>
          <LoginContainer>
            <Button type="primary" htmlType="submit" className="login-form-button" onClick={this.handleSubmit}>
              Log in
            </Button>
          </LoginContainer>
        </Form>
      </FormContainer>
    );
  }
}

const mapDispatchToProps = { login: loginRequest };
const WrappedLoginForm = Form.create()(LoginForm);

export default connect(null, mapDispatchToProps)(WrappedLoginForm);

我的动作:

export const loginRequest = (data: ICredentials): Action => ({
  type: Actions.LoginRequest,
  payload: data,
});

我的减速机:

const initialState: State = {
  loading: false,
}

const reducer: Reducer<State> = (state = initialState, action: Actions & any) => {
  switch (action.type) {
    case Actions.LoginRequest:
      return {
        ...state,
        loading: true,
      }

    case Actions.LoginSuccess:
      return {
        ...state,
        loading: false,
      }

    default:
      return state;
  }
}

export default reducer;

我的萨加斯:

import { all, call, takeLatest, put } from 'redux-saga/effects';
import axios from 'axios';
import { push } from 'react-router-redux'
import message from 'antd/lib/message';
import { loginRequest, LoginRequest, loginSuccess } from './actions';
import { ICredentials } from './model';
import { AccessToken } from '../../storage/token';

const login = (payload: ICredentials) => axios({
  method: 'POST',
  url: //....
  data: {
    username: payload.username,
    password: payload.password,
    grant_type: 'password',
    scope: 'admin,super_admin',
  },
  headers: {
    'Content-Type': 'application/json',
    Authorization: //....
  }
});

function* loginSaga({ payload }: LoginRequest) {
  try {
    const data = yield call(login, payload);
    AccessToken.set({ ...data.data, retrieved_at: Date.now() / 1000 })
    yield call(message.success, 'Welcome!');
    // yield all([
    //   put(loginSuccess()),
    //   put(push('/'))
    // ]);
    // yield put(loginSuccess());
    // yield put(push('/'))
  } catch (err) {
    console.log(err)
  }
}

function* watcherSaga() {
  yield takeLatest(loginRequest, loginSaga)
}

export default watcherSaga;

在这个故事中,设置AccessToken时,我理想情况下是想使用react-router-redux将用户推到另一条路线。但是,似乎正在进行一个神秘的API调用,但由于没有传递凭据而失败了。enter image description here

此处显示的是API调用,返回200,但随后又返回400,因为它再次寻找username

我怀疑这可能是错误的表单,尽管我不想切换到另一个表单库,但我觉得我可能必须这样做。有人有什么想法吗?

1 个答案:

答案 0 :(得分:1)

takeLatest理想情况下必须提供一个字符串。在您的情况下,传递了一个返回对象的函数。

takeLatest不检查对象的内容(即键和值)。那是您必须自己做的事情。

因此,无论分派了什么操作,都会启动登录传奇,该调用会调用登录api,并带有不适当的有效负载,从而导致错误。

因此,为避免错误,您可以将字符串传递给takeLatest或换句话说,只有在分派Actions.LoginRequest(类型为Actions.LoginRequest的动作)时才启动登录传奇。 / p>

yield takeLatest(Actions.LoginRequest, loginSaga)