4

Normally in HTML you do something like this:

<form> 
    <input type="text"/>
    <input type="text"/>
    <input type="submit"/>
</form>

I believe this is not the React way to do it.

Another way to do like i did in my app, is not the best way to do as well i believe. Like this:

buttonclickRequest(){
  var reasonn = document.getElementById("testControl").value;
}

<div>
   <FormControl id="testControl"/>
   <Button id="btnRequest" onClick={this.buttonclickRequest}/>
</div>

In other stackoverflow topics I saw examples like this:

constructor(props) {
  super(props);
  this.state = {
    firstName: '',
    lastName: '',
    place: '',
    address: '',
    email: '',
    phoneNumber: ''
  };
}
handleClick() {
  //do something
}

handleChange = (e) => {
  this.setState({
     [e.target.id]: e.target.value
  })
}

<div>
   <input type="text" onChange={e => this.handleChange(e)}/>
   <button type="submit" onClick={this.handleClick}/>
</div>

But i have my questions at this point as well,

I don't know how to do this properly with multiple text inputs:

  1. You can make multiple specific changehandlers which is inefficiënt,

  2. You can make a changehandler with a switch to set the properties

Is it even efficient to do a handle change on the inputfields? Because I just want the inputfield values when the button is clicked..

This is the form I'm talking about.

Create customer form

So how to properly get the multiple input data with React, when the button is clicked?

Thanks for your help in advance!

Nagama Inamdar
  • 2,851
  • 22
  • 39
  • 48
Salomé
  • 303
  • 1
  • 4
  • 14
  • create a component for `textbox`. it maintains its own state and takes a callback on value change. your parent component can manage all child component states as the callback will be passed to textbox component – hannad rehman Dec 11 '18 at 13:20
  • It is performant if you change a bit of code. You are currently creating a new function everytime you type something into the input (arrow func). Instead, you can do it this way: ``. – SkyzohKey Dec 11 '18 at 13:36
  • [found this link](https://gist.github.com/krambertech/76afec49d7508e89e028fce14894724c) use setTimeout and Cleartimeout – Dhaval Pankhaniya Jun 27 '20 at 19:10

3 Answers3

4

I think first you should add name attribute to your input field and use the name to set the state and then use the state on handleClick:

constructor(props) {
  super(props);
  this.state = {
    firstName: '',
    lastName: '',
    place: '',
    address: '',
    email: '',
    phoneNumber: ''
  };
}
handleClick = () => {
  //do something
  console.log(this.state);
  // should be something like this {
  //  firstName: '',
  //  lastName: '',
  //  place: '',
  //  address: '',
  //  email: '',
  //  phoneNumber: ''
  //}
}

handleChange = (e) => {
  this.setState({
    [e.target.name]: e.target.value
  })
}

render() {
  return(
    <div>
      <input type="text" name="firstName" onChange={this.handleChange}/>
      <input type="text" name="lastName" onChange={this.handleChange}/>
      <button type="submit" onClick={this.handleClick}/>
    </div>
  )
}

Note that the name should match the state key.

Kabbany
  • 515
  • 2
  • 7
  • 1
    Well this works indeed thanks, but is this the most efficient way? Because it will call the onChange function everytime a character is added. – Salomé Dec 11 '18 at 13:57
  • 2
    I think it is, calling onChange with every character is not a big issue – Kabbany Dec 11 '18 at 14:05
2

Assuming you may be looking for state values

constructor(props) {
  super(props);
  this.state = {
    firstName: '',
    lastName: '',
    place: '',
    address: '',
    email: '',
    phoneNumber: ''
  };
}
handleClick() {
  console.log("State ==>", this.state);
}

setFirstName = (e) => {
  this.setState({
     firstName: e.target.value
  })
}

setPhoneNumber = (e) => {
  this.setState({
     phoneNumber: e.target.value
  })
}

render(){
return('
<div>
   <label> First Name </label>
   <input type="text" name="firstName" onChange={e => this.setFirstName(e)}/>
   <label> Phone Number </label>
   <input type="text" name="phoneNumber" onChange={e => this.setPhoneNumber(e)}/>
   <button type="submit" onClick={this.handleClick}/>
</div>
')
}
Nagama Inamdar
  • 2,851
  • 22
  • 39
  • 48
  • This is highly inefficient and forces you to write more code for each inputs. The OP example is the way to go for efficientness. See my comment on OP's post to see why he's code was not performant. – SkyzohKey Dec 11 '18 at 13:38
  • But this indeed like SkyzohKey says, changes the state whenever i type a character.. Eventhough i only need it to retrieve when i press the button. – Salomé Dec 11 '18 at 13:49
  • And indeed i have to write a lot of code, which i dont want to – Salomé Dec 11 '18 at 13:59
  • 1
    If you are trying to maintain state values which might need to be passed to other components its better to maintain its keys irrespective of the id's of the input fields. Plus you can also save them in a global state instead of making use of local states. – Nagama Inamdar Dec 12 '18 at 09:26
1

and yes... you are right creating change handlers for each input its not efficient on your case, what you need is a react form that gives you the old and submit options,you cant use old form because it needs to update the page to retrieve the values.

I Suggest you to use Antd form witch gives you all in components, i even suggest you to use their Input components witch look very nice and handles pretty well. Antd Design (User interface components for react) - Antd some sample code. give it a try !!! CodeSandbox

  • You don't need a React Form Manager for managing 6 textfields. All you need is performance. And that's not 6 onChange handlers that will kill your perfs. It is not possible to trigger onChange for multiple fields at the same time so... The only error made by OP is to create a new Arrow function anytime he write something into a textfield. – SkyzohKey Dec 11 '18 at 13:41
  • 1
    Yes you are right to,it will not kill performance, and it's not about that, but why not promote better programming! This is not one case input to the user fill, it's a form you need the values on the end when all it's filled and of you add the validations? That's the definition of form multiple fields basically... – Hugo Barragon Dec 11 '18 at 13:53
  • 1
    The benefits of setting state when user type is that you can actually have live form validation. Also, once user clicks on the button, you can basically get `this.state` and get values from there. I don't understand how adding complexity into a project helps "promoting better programming". Less code is better. – SkyzohKey Dec 11 '18 at 13:58
  • You both have good arguments, thanks for this! Made me think again in the right direction – Salomé Dec 11 '18 at 14:02
  • With form you have form validation live to, I don't think it's complex...the code will be easily readable othewise will have too look for eatch setstate ,booth are solutions maybe search a bit what u need, but that's a form – Hugo Barragon Dec 11 '18 at 14:13