javascript - Antd form and redux integration, how to handle front-end and back-end validation at the same time?
習慣沉默
習慣沉默 2017-05-19 10:11:17
0
1
1067

A project I was working on recently used Antd and reac-redux, and there was a form mention in it. My requirement is to perform front-end verification when the user inputs. Here I use the getFieldDecorator provided by Antd; when the user submits the form, the error message returned by the backend is mapped to the form. Here I use the Antd provided Custom validation, namely the help and validateStatus attributes of FormItem.

But I found that when using custom validation, getFieldDecorator no longer works. So if you want to use getFieldDecorator verification, but also want to use custom verification when the backend returns data, how should you deal with it?

Thank you all in advance.

Attached code snippet:

UI components

    submitLogin = (e) => {
        e.preventDefault();
        // 前端验证
        this.props.form.validateFields((err, values) => {
            if (!err) {
                // 前端验证无误,向后端提交
                this.props.submitLoginForm(values);
            }
        });
    };
    render() {
        const { getFieldDecorator } = this.props.form;
        // 后端返回结果
        const access = this.props.loginState.results;
        const rulesGenerate = {
            email: getFieldDecorator('email', {
                        rules: [
                            { required: true, message: '请填写邮箱' },
                            { type: 'email', message: '邮箱格式不对' },
                        ]
                    })
        };
        // 服务器返回的数据是否有error
        const errors = access.error?access.error:false;
        return (
            <Form onSubmit={this.submitLogin} className="login-form">
                <FormItem
                    className="login-form__item"
                    validateStatus={errors&&errors.email?'error':''}
                    help={errors&&errors.email?errors.email:''}
                >
                    {rulesGenerate.email(
                        <Input addonBefore={<Icon fontSize="20" type="user" />} placeholder="用户名 / ID / 手机号" />
                    )}
                </FormItem>
            </Form>
       );

Container component

// 传送state到UI组件的props
const mapStateToProps = (state) => {
    return {
        loginState: state.loginReducer
    }
}

// 派发事件
const mapDispatchToProps = (dispatch) => {
    return {
        submitLoginForm: (values) => {
            dispatch(loginProcessing(values))
        }
    }
}

// 连接UI组件
const ShowForm = connect( mapStateToProps,mapDispatchToProps )(Login)

Action

// start fetching data
export const LOGIN_STARTING = 'LOGIN_STARTING'
function loginStarting(isLogging) {
    return {
        type: LOGIN_STARTING,
        isLogging
    }
}
// fetched data successfully
export const LOGIN_SUCCEEDED = 'LOGIN_SUCCEEDED'
function loginSucceeded(isLogging,results,fields) {
    return {
        type: LOGIN_SUCCEEDED,
        isLogging,
        results,
        fields
    }
}
// meet some errors after fetching
export const LOGIN_FAILED = 'LOGIN_FAILED'
function loginFailed(isLogging,results) {
    return {
        type: LOGIN_FAILED,
        isLogging,
        results
    }
}

export function loginProcessing(values) {
    return function (dispatch, getState) {
        let loginData = new FormData();
        loginData.append('email', values.email);

        dispatch(loginStarting(true));
        return fetch(`api/login`,{
            method: 'POST',
            body: loginData
        })
        .then(response => response.json())
        .then(response =>{
            return dispatch(loginSucceeded(false,response,values))
        }).catch(error =>
            dispatch(loginFailed(false,error))
        );
    }
}

Reducer

import
{
    LOGIN_STARTING,
    LOGIN_SUCCEEDED,
    LOGIN_FAILED
} from '../action.js';

const initialState = {
  isLogging: false,
  results: {},
  fields: {}
};

export default function formReducer(state = initialState, action) {
    switch (action.type) {
        case LOGIN_STARTING:
              return Object.assign({}, state, {
                isLogging: action.isLogging
              })
        case LOGIN_SUCCEEDED:
              return Object.assign({}, state, {
                isLogging: action.isLogging,
                   results: action.results,
                   fields: action.fields
            })
        case LOGIN_FAILED:
              return Object.assign({}, state, {
                isLogging: action.isLogging,
                   results: action.results
            })
        default:
              return state;
    }
}
習慣沉默
習慣沉默

reply all(1)
洪涛

Use the this.props.formsetFields method, official example: server-validate

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template