Search code examples
reactjsonchangesetstate

Single onChange handler for webForm in React


this.state = {
 data : { 
            name : {fname : 'sinni' , lname : 'jain' },
            address : { city : 'jodhpur' , state : 'rajasthan'}
            sex : 'male'
        }
  status : 'idiot'    
}


in render fuction...

render ()
{ 
     const { data , status } = this.state;

    return (
              <form>
                  <p> first name </p>
                  <input type='text' value={data.name.fname} onChange={changeHandler} />
                  <p> last name </p>
                  <input type='text' value={data.name.lname} onChange={changeHandler} />
                   
                   {//so on whole form }
                   { and sex and status are select box }

              </form>
           


   )
}
enter code here

I have the whole form for input entries like this...

How do I create an onChangeHandler function so all values can be updated.

How can I manage [even.target.name] and how can I assign it using setState so the rest of data won't be affected.


Solution

  • First, you need to give a name to every input and data-parent if it nested property

    Name must be a key of property which you want to change in state

    And data-parent attr, which will be the name of the nested component

    Please check the example below

    https://codesandbox.io/s/react-input-example-forked-tu7hp?file=/src/index.js

    
    class MyComponent extends React.Component {
      state = {
        data: {
          name: { fname: "sinni", lname: "jain" },
          address: { city: "jodhpur", state: "rajasthan" },
          sex: "male"
        }
      };
    
      changeHandler = (e) => {
        const parent = e.target.dataset.parent;
        const name = e.target.name;
        const newValue = e.target.value;
        this.setState((prevState) => {
          if (parent) {
            return {
              data: {
                ...prevState.data,
                [parent]: {
                  ...prevState.data[parent],
                  [name]: newValue
                }
              }
            };
          } else {
            return {
              data: {
                ...prevState.data,
                [name]: newValue
              }
            };
          }
        });
      };
    
      render() {
        const { data } = this.state;
        return (
          <div>
            <input
              type="text"
              name="fname"
              data-parent="name"
              value={this.state.data.name.fname}
              onChange={this.changeHandler}
            />
            <input
              type="text"
              name="lname"
              data-parent="name"
              value={this.state.data.name.lname}
              onChange={this.changeHandler}
            />
            <input
              type="text"
              name="city"
              data-parent="address"
              value={this.state.data.address.city}
              onChange={this.changeHandler}
            />
          </div>
        );
      }
    }