gjvatsalya
gjvatsalya

Reputation: 1169

What is the right way to go about forms when using React and Redux?

I have a Details.js redux-smart component with the following form:

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

    render() {
        return (
            <form className='form'>
                <NumberInput label='Field1:' name='Field1' value={this.props.editedGroup.field1} changeHandler={this.props.inputChangeHandler.bind(null, 'FIELD1_CHANGED')} />
                <NumberInput label='Field2:' name='Field2' value={this.props.editedGroup.field2} changeHandler={this.props.inputChangeHandler.bind(null, 'FIELD2_CHANGED')} />
                <NumberInput label='Field3:' name='Field3' value={this.props.editedGroup.field3} changeHandler={this.props.inputChangeHandler.bind(null, 'FIELD3_CHANGED')} />
                <TextInput label='Field4:' name='Field4' value={this.props.editedGroup.field4} changeHandler={this.props.inputChangeHandler.bind(null, 'FIELD4_CHANGED')} />
                <TextInput label='Field5:' name='Field5' value={this.props.editedGroup.field5} changeHandler={this.props.inputChangeHandler.bind(null, 'FIELD5_CHANGED')} />
            </form>
        );
    }
}

function mapStateToProps(state) {
    return {
        editedGroup: state.editedGroup
    }
}

function mapDispatchToProps(dispatch) {
    return {
        inputChangeHandler: function(type, data) {
            dispatch(formChange(type, data));
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Details);  

My action is obviously pretty simple:

export function formChange(type, event) {
    return {
        type: type,
        data: event.target.value
    };
}

And here is my reducer:

var initialStateForEditedGroup = {
    field1: '',
    field2: '',
    field3: '',
    field4: '',
    field5: ''
};
function editedGroup(state = initialStateForEditedGroup, action) {
    switch (action.type) {
        case "FIELD1_CHANGED":
            return Object.assign({}, state, {field1: action.data});
        case "FIELD2_CHANGED":
            return Object.assign({}, state, {field2: action.data});
        case "FIELD3_CHANGED":
            return Object.assign({}, state, {field3: action.data});
        case "FIELD4_CHANGED":
            return Object.assign({}, state, {field4: action.data});
        case "FIELD5_CHANGED":
            return Object.assign({}, state, {field5: action.data});
        default:
            return state;
    }
}

Sorry for the long text of boilerplate code, but I figured it might be useful.

So I have an action for every input and I'm handling the state changes in the reducer as dictated by redux.

But my question is: wouldn't this re-render the entire form every time someone enters a value in one of the fields?

As far as I know, "connect" from react-redux will check if the current state object is different from the next updated state object. If it is different, it will re-render the entire Details component everytime instead of just that specific input field.

This leads me to believe that I'm going about this the wrong way. If I enter a value for "Field1", I don't want the other fields to get re-rendered but I think that is what will happen since I'm returning a new object every time in the reducer if any of the input fields change.

I know that we have the redux-forms plugin, but I would like to wrap my head around the logic of handling forms when using react/redux.

EDIT:
So I was thinking that I could perhaps change my "mapStateToProps" function like this:

function mapStateToProps(state) {
    return {
        field1: state.editedGroup.field1,
        field2: state.editedGroup.field2,
        field3: state.editedGroup.field3,
        field4: state.editedGroup.field4,
        field5: state.editedGroup.field5,
    }
}  

This way only one of the props will get updated every time. But at the same time, correct me if I'm wrong, if one of the props gets updated, the whole thing gets re-rendered again?
If so, then this way would be useless.

Upvotes: 1

Views: 100

Answers (1)

Jim Bolla
Jim Bolla

Reputation: 8295

Yeah. What you're saying is correct. That exact issue is what dictated the major design change in redux-form between versions 5 and 6.

Upvotes: 1

Related Questions