Search code examples
reactjsreact-routerredux-form

React Router + Redux Form + Edit/New Component == Fail


I'm trying to create a React component that is capable either to create or edit an existing item in my database. Everything is working fine, except one thing: when I call a route new from the edit route (the same component with different behavior), React simply keeps the previous form state and I can't see a new form with empty data. It only works when I call the new route from somewhere else.

Possible routes:

  • /bastions/new - Renders the component with no data

  • /bastions/:id - Renders the component with an existing data

Is this problem familiar for someone?

Just some code to make things cleaner (with the most relevant peaces):

Thanks in advance.

class BastionForm extends Component {

    componentWillMount() {      
        if(this.props.bastion.number) {      
            this.props.fetchBastion(this.props.params.number);
        }
    }

    renderField({ input, label, type, meta: { touched, error, warning } }) {
        return (
            <FormGroup controlId={label} {...validation}>
                <ControlLabel>{label}</ControlLabel>
                <FormControl {...input} placeholder={label} type={type} />
                <FormControl.Feedback />
            </FormGroup>
        );
    }

    render() {
        const { handleSubmit, pristine, reset, submitting } = this.props;

        return (
            <form onSubmit={handleSubmit(this.onSubmit.bind(this)) }>
                <h3>Create a new Bastion</h3>

                <Field name="sample" type="text" component={this.renderField} />

                <ButtonToolbar>
                    <Button bsStyle="primary" disabled={submitting}>Submit</Button>
                </ButtonToolbar>
            </form>
        );
    }
}

BastionForm = reduxForm({
    form: 'BastionForm',
    enableReinitialize: true
})(BastionForm);

BastionForm = connect(
    state => ({
        initialValues: state.bastions.bastion
    }), { fetchBastion }
)(BastionForm);

export default BastionForm;

Solution

  • componentWillMount is only invoked once before mounting occurs. Since /bastions/new and /bastions/:id are actually referring to the same route, BastionForm will not be unmounted when your path changes from /bastions/:id to /bastions/new. So you can decide whether showing an existed data or showing with no data through changing the state of BastionForm(dispatch an action). Then handle the props change in componentWillReceiveProps.