1

An example I came across:

I recently came across the following example:

activate(event) {
  console.log(event.target.value);
}

render() {
  return ( 
    <div onChange={this.activate.bind(this)}>
      <input type="radio" value="yes" name="confirm"/> Yes
      <input type="radio" value="no" name="confirm"/> No
    </div>
   )
}

This allows an onChange handler to be applied to a parent div of radio buttons rather than each individual radio button.

My questions about this:

  1. Is there any reason why the onChange attribute would be specifically applied to a group of radio buttons and not to groups of other form elements?
  2. Why not place all form fields inside a single div or form element and have only one onChange attribute?
  3. Is this specific to ReactJS, or can something similar be done in basic JavaScript?
kojow7
  • 10,308
  • 17
  • 80
  • 135

4 Answers4

0

I'm not a pro in React but i could say a few things :

  1. You can put onChange on every types of inputs, it's working with select, text, checkboxes.

  2. It's better to use onChange or any listeners directly on the input itself, why ? Because in this function you can easily refer to your input with the "event" params, like that :

    function handleChange(event) { var value = event.target.value; }

If you don't do it, you have to refer to the right input and it can be really a mess.

jacman
  • 191
  • 9
  • 1
    In regards to number 2, it seems to get the correct target even if do not apply it directly to the specific input. If you look at my example again you can see that I am using event.target.value in the activate function and it is therefore linked to the proper target. – kojow7 Jul 03 '17 at 20:45
  • Yes, re 2, you can get `event.target.value` from an event listener in a parent component due to [Event Bubbling and Capture](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Eventsvent_bubbling_and_capture) – iansedano Sep 27 '21 at 06:41
0

The shortest I know and works great:

handleInputChange = ({ target: { name, value } }) => {
  this.setState({ [name]: value })
}

Keep in mind:

  • you need to add the name="name" attr to the input tags,
  • you also need to have the correspondent name in the state.

Check this snippet and play with it adding more text fields (it's magical):

class SingleHandler extends React.Component {
  state = {
    title: '',
    description: ''
  }
  
  handleInputChange = ({target: { name, value }}) => {
    this.setState({ [name]: value });
  }

  render() {
    return (
      <div>
        <label htmlFor="title">title: {this.state.title}</label>

        <input
          type="text"
          name="title"
          value={this.state.title}
          onChange={this.handleInputChange}
        />
        <label htmlFor="description">description: {this.state.description}</label>

        <input
          type="text"
          name="description"
          value={this.state.description}
          onChange={this.handleInputChange}
        />
      </div>
    );
  }
}

ReactDOM.render(<SingleHandler />, document.body);
input, label {
  display: block;
  width: 80%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Sources: https://reactjs.org/docs/forms.html (here you'll find a version that also works for different types of inputs) https://medium.com/@tmkelly28/handling-multiple-form-inputs-in-react-c5eb83755d15 (great resource also)

diegoalmesp
  • 162
  • 1
  • 13
  • I don't think this answers the question though. It seems you are just giving a way to write a form in React, whereas the question is about using event bubbling within React. – iansedano Sep 27 '21 at 06:39
0

1. Is there any reason why the onChange attribute would be specifically applied to a group of radio buttons and not to groups of other form elements?

No, there is no reason why it couldn't be applied to other form elements or even the root element of the DOM. All events go from the root to the target (the capture phase) and then back to the root (the bubbling phase). The event handler just has to be written with this in mind. See this SO thread for more info on event bubbling.

2. Why not place all form fields inside a single div or form element and have only one onChange attribute?

This is usually true when it comes to vanilla JS. However, React implements its own event system, and the way that they seem to advise is to create an event listener and then link each input to it.

<form onSubmit={handleSubmit}>
    <input type="text" onChange={handleChange} />
    <input type="text" onChange={handleChange} />
    <input type="text" onChange={handleChange} />
</form>

The handleChange function will use event.target.value whether it uses event bubbling or not, but React seems to prefer that you explicitly attach the function to each input element.

If you don't, it's common to run into warnings when you try to set default values:

enter image description here

(default values have also been a common source of confusion, more info here)

It is just a warning. This warning has been the subject of a large discussion on the Github repo, more discussion on that below.

3. Is this specific to ReactJS, or can something similar be done in basic JavaScript?

As mentioned, this is not specific to React, it is in fact more specific to JS. React seems to be agnostic about it. It would seem that they prefer you add the onChange reference to each input element and not use bubbling in this way.

What is the right way?

I don't know. I think it comes down to what you prefer, or what the situation calls for.

In the large discussion on the Github repo, most people there run into the warnings because using event bubbling is usually the way that is encouraged as 'best practice' in vanilla JS. However, there are also voices that say:

This is my opinion, but I'd say it's the opposite, it's a bad idea. It relies on bubbling outside of the React hierarchy.

link to comment

So depending on who you ask, using event bubbling may be considered against the trend of React thinking. It will depend on how you choose to architect your app.

Its important to note that there is no real issue with it, everything works. Whether you use event bubbling or not. The main gripe, in the issue, seems to come down to the fact that the console becomes crowded with warnings and there is no elegant way to turn them off. The best way appears to be to just assign an empty function to the input elements.

iansedano
  • 6,169
  • 2
  • 12
  • 24
0
activate(event) {
  console.log(event.target.value);
}

render() {
  return ( 
    <div>
     {
       ["yes","no"].map((item,i)=>(
         <>
             <input
               key={i}
               type="radio" 
               value={item}
               name="confirm"
               onChange={(e)=>activate(e)}/> {item}
         </>
        ))
     }
     </div>
   )
}
Ayush Singh
  • 116
  • 6