无法以Redux形式抛出SubmissionError

时间:2018-06-29 17:21:39

标签: reactjs redux react-redux axios redux-form

我正在尝试以Redux形式显示SubmissionError(如果后端服务器响应不是状态码200),但是由于我在React的初学者水平,我不确定该怎么办, Redux,React Redux,Redux Form和Axios。通过浏览各种SO帖子和Github问题,我已经尝试了很多事情(目前已从中恢复过来)。如果有人可以帮助我,将不胜感激!

我当前遇到的错误是未承诺的承诺消息: error screenshot

尽管我的项目中有更多文件,但是这里有相关文件(减去import语句):

ssoLoginPage.js

const renderField = (field) => {
    const { input, label, name, type, meta: { touched, error } } = field;
    const placeholder = `Enter ${label} here`;
    return(
        <div className="slds-form-element slds-m-bottom--large">
            <label className="slds-form-element__label" htmlFor={label}>
                {label}
            </label>
            <div className="slds-form-element__control">
                <input
                    key={name}
                    id={name}
                    className="-input"
                    type={type}
                    placeholder={placeholder}
                    {...field.input}
                />
            </div>
            {touched && error && <span>{error}</span>}
        </div>
    );
};

class SsoLoginPage extends React.Component {
    constructor(props) {
        super(props);
    }
    onSubmit(values) {
        this.props.ssoLogin(values, () => {
            throw new SubmissionError({_error: "One or more credentials are incorrect"});
        });
    }
    render() {
        console.log("ssoLoginStatus:",this.props.ssoLoginStatus);
        const { error, handleSubmit} = this.props;
        return (
            <IconSettings iconPath="/slds-static-2.6.1/assets/icons">
                <div>
                    <Modal
                        title="SSO Login"
                        isOpen={!this.props.ssoLoginStatus}
                        onRequestClose={this.toggleOpen}
                        dismissOnClickOutside={false}
                    >
                        <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
                            <Field
                                name="username"
                                type="text"
                                component={renderField}
                                label="Username"
                            />
                            <Field
                                name="password"
                                type="password"
                                component={renderField}
                                label="Password"
                            />
                            <Field
                                name="verificationCode"
                                type="password"
                                component={renderField}
                                label="Verification Code"
                            />
                            {error && <strong>{error}</strong>}
                            <Button type="submit" label="Login" variant="brand" />
                        </form>
                    </Modal>
                </div>
            </IconSettings>
        );
    }
}

function mapStateToProps({ssoLoginStatus}) {
    return ssoLoginStatus;
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({ssoLogin},dispatch);
}

export default reduxForm({
    form: "ssoForm" // a unique identifier for this form
})(
    connect(mapStateToProps,mapDispatchToProps)(SsoLoginPage)
);

settings.setAppElement("#root");

reducersIndex.js

const rootReducer = combineReducers({
    ssoLoginStatus: ssoReducer,
    form: formReducer
});

export default rootReducer;

ssoReducer.js

const ssoProcess = (state, action) => {
    console.log("ssoLogin action:",action);
    switch(action.payload.status) {
        case 200:
            //everything's okay
            console.log("reaching 200 case?");
            return {...state, "ssoLoginStatus": true};
        default:
            //not sure what to do here currently
            return state;
    }
};

export default function(
    state={"ssoLoginStatus": false}, action) {
    console.log("action type:",action.type);
    switch (action.type) {
        case SSO_LOGIN:
            console.log("return something here hopefully");
            return ssoProcess(state, action);
        default:
            return state;
    }
}

actionsIndex.js

export const SSO_LOGIN  = "SSO_LOGIN";
export const BASE_URL = "http://localhost:8080";

export function ssoLogin (values, callback) {
    console.log("went inside ssologin action creator!",
        values.username,
        values.password,
        values.verificationCode);
    const url = `${BASE_URL}/ssologin?username=${values.username}&password=${values.password}&verificationCode=${values.verificationCode}`;
    console.log("url w/ params:",url);
    const request = axios
        .post(url,{responseType: "json"})
        .then(response => {
            console.log("axios response: ",response);
            return response;
        })
        .catch(error => {
            console.log("sso error: ",error);
            return callback();
        });
    return {
        type: SSO_LOGIN,
        payload: request
    };
}

1 个答案:

答案 0 :(得分:0)

如果您刚开始使用react / redux,我建议您使用redux-saga。

查看ActionCreators-> startSubmit(form:String)-> stopSubmit(form:String, errors:Object) https://redux-form.com/6.0.0-alpha.5/docs/api/actioncreators.md/

您可以在提出请求之前尝试使用startSubmit('ssoForm'),如果请求为200,并且在stopSubmit('ssoForm', { _error: error })部分有错误catch,则可以停止stopSubmit('ssoForm');

由于我没有axios示例,所以我事先表示歉意。我将为您提供我的传奇示例,以便您查看流程:

function* signIn({ payload }) {
  try {
    const { username, password } = payload;
    yield put(actions.setState({ isLoading: true }));
    yield put(startSubmit('signin'));
    yield call([Auth, 'signIn'], username, password);
    yield put(actions.getUser());
    yield put(stopSubmit('signin'));
  } catch (error) {
    yield put(actions.setState({ ...defaultState }));
    yield put(stopSubmit('signin', { _error: error }));
  }
}