我有一个登录表单(由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调用,但由于没有传递凭据而失败了。
此处显示的是API调用,返回200,但随后又返回400,因为它再次寻找username
我怀疑这可能是错误的表单,尽管我不想切换到另一个表单库,但我觉得我可能必须这样做。有人有什么想法吗?
答案 0 :(得分:1)
takeLatest
理想情况下必须提供一个字符串。在您的情况下,传递了一个返回对象的函数。
takeLatest
不检查对象的内容(即键和值)。那是您必须自己做的事情。
因此,无论分派了什么操作,都会启动登录传奇,该调用会调用登录api,并带有不适当的有效负载,从而导致错误。
因此,为避免错误,您可以将字符串传递给takeLatest
或换句话说,只有在分派Actions.LoginRequest
(类型为Actions.LoginRequest
的动作)时才启动登录传奇。 / p>
yield takeLatest(Actions.LoginRequest, loginSaga)