提交和分发后,React会获得更新的道具

时间:2018-09-19 08:03:26

标签: reactjs react-redux

我是新来的React和react-redux。我目前正在根据这篇很棒的文章https://medium.com/@l_e/writing-a-wizard-in-react-8dafbce6db07做一个用户注册向导,并做了一些修改。

这里是RegisterWizard组件:

import React from 'react';
import { connect } from 'react-redux';
import { Step1 } from './Step1'
import { Step2 } from './Step2'

class RegisterWizard extends React.Component {

    constructor(props){
        super(props);

        this.state = {
            currentStep: 1,
            user: {
                full_name: '',
                email: '',
                phone_number: '',
                password: '',
                confirm_password: ''
            }
        };

        this._next = this._next.bind(this);
    }

    _next(data) {
        let { user, currentStep } = this.state;
        let { full_name, phone_number, password, confirm_password } = data;

        if (currentStep >= 1) {
            currentStep = 2;
        } else {
            currentStep = currentStep + 1;
        }

        this.setState({
            currentStep: currentStep
        });

        if (full_name) {
            this.setState({
                user: {
                    ...user,
                    full_name
                }
            });
        }

        if (phone_number) {
            this.setState({
                user: {
                    ...user,
                    phone_number
                }
            });
        }

        if (password) {
            this.setState({
                user: {
                    ...user,
                    password
                }
            });
        }

         if (confirm_password) {
            this.setState({
                user: {
                    ...user,
                    confirm_password
                }
            });
        }
    }

    render() {
        console.log(this.state.user)
        const { currentStep } = this.state;
        return(
           <div className="block-center mt-4 wd-xl">
                <div className="card card-flat">
                    <Step1 currentStep={currentStep} afterValid={this._next} />
                    <Step2 currentStep={currentStep} afterValid={this._next} />
                </div>
            </div>
       );
    }
}

const connectedRegisterWizard = connect(null, null)(RegisterWizard);
export { connectedRegisterWizard as RegisterWizard };

这里是Step 1组件。我正在通过API处理我的验证

import React from 'react';
import { connect } from 'react-redux';
import { Input } from 'reactstrap';
import { userActions } from './../../../_actions';

class Step1 extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            full_name: ''
        }

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        const { name, value } = event.target;
        this.setState({
            ...this.state,
            [name]: value
        });
    }

    handleSubmit(event) {
        event.preventDefault();-

        const { full_name } = this.state;
        const { dispatch } = this.props;
        const names = full_name.split(" ");
        const [first_name, last_name, ...other_names] = names 

        this.setState({
            ...this.state,
            submitted: true
        });

        dispatch(userActions.register({
            ...this.state,
            first_name: first_name ? first_name : '',
            last_name: last_name ? last_name : '',
            other_names: other_names ? other_names.join(" ") : '',
        }));
         // I want to get the new formErrors from props after the above

    }

    _validate() {
        /*Only call this after a check is mad to make sure
         that there are no errors for first_name */

        let { full_name } = this.state
        this.props.afterValid({
            full_name
        })
    }

    render() {
       if (this.props.currentStep !== 1) {
         return null;
       } 

       const { full_name } = this.state;
       const { requesting, formErrors, alert } = this.props;

       return(
            <div>
            <div className="card-header text-center bg-info">
                <p className="text-center py-2">What is your full name?</p>
            </div>
            <div className="card-body">
                 <form className="mb-3" onSubmit={this.handleSubmit}>
                    <div className='form-group'>
                        <label className="text-muted" htmlFor="full_name">Full Name</label>
                        <div className="input-group with-focus">
                            <div className="input-group-prepend">
                                <span 
                                className="input-group-text text-muted border-right-0">
                                    <em className="fa fa-user"></em>
                                </span>
                            </div>
                            <Input type="text" className="border-left-0" name="full_name" 
                            value={full_name} onChange={this.handleChange}/>
                            {
                                formErrors.map((error, i) => 
                                    error.pointer == 'first_name' &&                                 
                                    <span key={i} className="invalid-feedback">{ error.message }</span>
                                )
                            }
                        </div>
                    </div>
                    <button className="btn btn-block btn-primary mt-3" 
                    type="submit">Next</button>
                </form>
            </div>
            </div>
        );
   }
}

function mapStateToProps(state) {
    const { alert } = state;
    const { requesting, formErrors } = state.registration;
    return {
        requesting,
        formErrors,
        alert,
    };
}


const connectedStep1 = connect(mapStateToProps)(Step1);
export { connectedStep1 as Step1 };

这是register中的userActions.js函数

function register(user) {
    return dispatch => {
        dispatch(request(user));
        dispatch(alertActions.clear());

        userService.register(user)
            .then(
                user => { 
                    dispatch(success());
                    dispatch(alertActions.success('Success! Please click on the activation link ' 
                        + 'sent to your email in order to login'));
                },
                error => {
                    const parsedError = errorHandler(error);
                    const {alertError} = parsedError;

                    if (alertError) {
                        dispatch(alertActions.error(alertError))
                    }

                    dispatch(failure(parsedError));
                }
            );
    };

    function request(user) { return { type: userConstants.REGISTER_REQUEST, user } }
    function success(user) { return { type: userConstants.REGISTER_SUCCESS, user } }
    function failure(error) { return { type: userConstants.REGISTER_FAILURE, error } }
}

这是register中的userService.js函数

function register(user) {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(user)
    };

    return fetch(`${config.apiUrl}/api/auth/register/`, requestOptions).then(handleResponse);
}

这里是regiStrationReducer.js

import { userConstants } from '../_constants';

const initialState = {
  requesting: false,
  formErrors: []
}

export function registration(state = initialState, action) {
  switch (action.type) {
    case userConstants.REGISTER_REQUEST:
      return { 
        ...state,
        requesting: true
      };
    case userConstants.REGISTER_SUCCESS:
      return {
        ...state,
        requesting: false,
        formErrors: []
      };
    case userConstants.REGISTER_FAILURE:
      return {
        ...state,
        requesting: false,
        formErrors: action.error.formErrors
      };
    default:
      return state
  }
}

仅当_validate()没有格式错误时,我才希望调用方法first_name,因此我想在执行以下命令后获取新的formErrors

 dispatch(userActions.register({
        ...this.state,
        first_name: first_name ? first_name : '',
        last_name: last_name ? last_name : '',
        other_names: other_names ? other_names.join(" ") : '',
    }));

当我提交表单时,将向userActions.register()进行调度。如何从道具中获得新的formErrors

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。我使用了componentDidUpdate。我做了

componentDidUpdate(prevProps) {
        if (this.props.formErrors != prevProps.formErrors) {
            let { formErrors } = this.props;
            let { submitted } = this.state;
            let pointers = formErrors.map(error => error.pointer);

            if (pointers.indexOf('first_name') == -1 && submitted) {
                this._validate();
            }
        }
    }