Home > Blockchain >  incorrect value of name attribute in event object
incorrect value of name attribute in event object

Time:10-03

I read about using a single handler for multiple input fields. When I'm trying to use that approach -> using event.target.value, I am getting just the first letter of what I entered in the input. Can anyone please help me on what I am doing wrong.

class AddContactForm extends Component {

    constructor(props) {
        super(props);
        this.name = "";
        this.email = ""
        this.phone = "";
    }


    componentDidUpdate() {
        console.log("updated");
    }

    componentWillUnmount() {
        console.log("unmounted");
    }

    componentWillMount() {
        console.log("mounted");
    }

    handleOnChange(event) {
        [event.target.name] = event.target.value;
        console.log(event)
        console.log(event.target.name);
        console.log(event.target.value);
    }

    addContact() {
        console.log("add");
        this.props.addContactHandler({
            name: this.name,
            email: this.email,
            phone: this.phone
        });
    }

    render() {
        return (
            <React.Fragment>
                <div className="mx-auto">
                    <div class="mb-3 row">
                        <label for="username" class="col-sm-2 col-form-label">Name</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" name='name' id="username" onChange={this.handleOnChange.bind(this)} />
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label for="mobileNumber" class="col-sm-2 col-form-label">Mobile Number</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" name="phone" id="mobileNumber" onChange={this.handleOnChange.bind(this)} />
                        </div>
                    </div>
                    <div class="mb-3 row">
                        <label for="emailId" class="col-sm-2 col-form-label">Email</label>
                        <div class="col-sm-10">
                            <input type="email" class="form-control" id="emailId" name="email" onChange={this.handleOnChange.bind(this)} />
                        </div>
                    </div>
                    <button className="btn btn-primary w-25" onClick={this.addContact.bind(this)}>Add</button>
                </div>
            </React.Fragment>
        )
    }
}

export default AddContactForm;

inside handle on change, the value of [event.target.name] always shows whatever was my first input alphabet. for If I am writong abcd ing input, ikt'll keep showing me a .

Where am I going wrong ?

CodePudding user response:

You haven't set the state properly in both constructor and handleChange functions.

Try this

import React, { Component } from "react";

class AddContactForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "",
      email: "",
      phone: ""
    };
  }

  componentDidUpdate() {
    console.log("updated");
  }

  componentWillUnmount() {
    console.log("unmounted");
  }

  componentWillMount() {
    console.log("mounted");
  }

  handleOnChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  addContact() {
    console.log("add");
    console.log(this.state);
    // this.props.addContactHandler(this.state);
  }

  render() {
    return (
      <React.Fragment>
        <div className="mx-auto">
          <div class="mb-3 row">
            <label for="username" class="col-sm-2 col-form-label">
              Name
            </label>
            <div class="col-sm-10">
              <input
                type="text"
                class="form-control"
                name="name"
                id="username"
                onChange={this.handleOnChange.bind(this)}
              />
            </div>
          </div>
          <div class="mb-3 row">
            <label for="mobileNumber" class="col-sm-2 col-form-label">
              Mobile Number
            </label>
            <div class="col-sm-10">
              <input
                type="text"
                class="form-control"
                name="phone"
                id="mobileNumber"
                onChange={this.handleOnChange.bind(this)}
              />
            </div>
          </div>
          <div class="mb-3 row">
            <label for="emailId" class="col-sm-2 col-form-label">
              Email
            </label>
            <div class="col-sm-10">
              <input
                type="email"
                class="form-control"
                id="emailId"
                name="email"
                onChange={this.handleOnChange.bind(this)}
              />
            </div>
          </div>
          <button
            className="btn btn-primary w-25"
            onClick={this.addContact.bind(this)}
          >
            Add
          </button>
        </div>
      </React.Fragment>
    );
  }
}

export default AddContactForm;

Check console logs enter image description here

Code sandbox URL => Edit epic-rubin-sgqex


If all of your fields are identical, you can even dynamically render them by mapping over the keys of the state object:

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

    this.state = {
      name: "",
      email: "",
      phone: ""
    };
  }

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

  render() {
    return (
      <React.Fragment>
        {Object.keys(this.state).map((key) => (
          <label>
            {key}
            <input
              type="text"
              name={key}
              onChange={this.handleOnChange}
              value={this.state[key]}
            />
          </label>
        ))}

        <pre>{JSON.stringify(this.state, null, 2)}</pre>
      </React.Fragment>
    );
  }
}

export default AddContactForm;

Edit spring-hill-ek0s8

CodePudding user response:

The issue is with the first line of code in this function.

handleOnChange(event) {
        [event.target.name] = event.target.value;
        console.log(event)
        console.log(event.target.name);
        console.log(event.target.value);
    }

That changes the HTML Input element name's first letter to the first letter of the input value you have typed.

Add with the following log

  handleOnChange = (event) => {
    [event.target.name] = event.target.value;
    console.log(event);
    console.log(event.target);
    console.log(event.target.name);
    console.log(event.target.value);
  };

enter image description here

Solution

To change the class variable dynamically, instead of

[event.target.name] = event.target.value;

use

this[event.target.name] = event.target.value;
  • Related