Andy Brady
Andy Brady

Reputation: 21

Can fields within the state be changed using setState depending on user input

I'm creating a form that will have three input fields and I want to change the state to what has been input. Instead of having to write three separate functions to handle all three inputs is there a way to set the state depending on the field the user has chosen to fill in?

Thanks in advance.

handleChange = e => {
        this.setState({
            //Can this be changed to target the right field in the state// : e.target.value
        })
    }
    render() {
        return (
            <div>
                <div>
                    <label htmlFor="name">Name:</label>
                    <input 
                        type="text"
                        value={this.state.name}
                        onChange={this.handleChange}
                    />
                </div>
                <div>
                    <label htmlFor="county">County:</label>
                    <input 
                        type="text"
                        value={this.state.county}
                        onChange={this.handleChange}
                    />
                </div>
                <div>
                    <label htmlFor="position">Position:</label>
                    <input 
                        type="text"
                        value={this.state.position}
                        onChange={this.handleChange}
                    />
                </div>
                <button>Submit Player</button>
            </div>
        )
    }

Upvotes: 0

Views: 180

Answers (2)

SAP
SAP

Reputation: 468

Here is the code

handleChange = e => {
    this.setState({
         [e.target.name]: e.target.value
    });
}
render() {
    return (
        <div>
            <div>
                <label htmlFor="name">Name:</label>
                <input 
                    type="text"
                    name="name"
                    value={this.state.name}
                    onChange={this.handleChange}
                />
            </div>
            <div>
                <label htmlFor="county">County:</label>
                <input 
                    type="text"
                    name="county"
                    value={this.state.county}
                    onChange={this.handleChange}
                />
            </div>
            <div>
                <label htmlFor="position">Position:</label>
                <input 
                    type="text"
                    name="position"
                    value={this.state.position}
                    onChange={this.handleChange}
                />
            </div>
            <button>Submit Player</button>
        </div>
    )
}

Upvotes: 3

jered
jered

Reputation: 11571

Rather than relying on anything in the DOM to identify the elements you want to update - which is not exactly best practice for React, because it confuses where the source of truth of state and model lie - you should abstract the form away entirely into a data structure:

state = {
    formInputs: [
        {
            name: 'Name',
            type: 'text',
            value: '',
        },
        {
            name: 'Country',
            type: 'text',
            value: '',
        },
        {
            name: 'Position',
            type: 'text',
            value: '',
        },
    ]
};
handleChange = (evt, n) => {
    this.setState((state) => {
        const arr = state.formInputs.slice();
        arr[n] = {value: evt.target.value, ...arr[n]};
        return {formInputs: arr};
    });
}
render() {
    return (
        <div>
            {this.state.formInputs.map((ea, i) => {
                return (
                    <div key={ea.name} >
                        <label htmlFor={ea.name}>{`${ea.name}:`}</label>
                        <input {...ea} onChange={(e) => {this.handleChange(e, i)}} />
                    </div>
                );
            })}
            <button>Submit Player</button>
        </div>
    );
}

Storing the data/inputs and their value in abstract component state -- and then using Array.map() to transform them into rendered UI -- is a very common and useful pattern in React.

Advantages:

  • Source of truth for state, the data model, and how to render it is completely unambiguous and 100% under React's control
  • Can add an arbitrary number of inputs and have them render dynamically
  • One single update function that will handle updating an arbitrary data field's stored value
  • Uses recommended React "controlled component" pattern

Upvotes: 1

Related Questions