How do you use onChange in React? - javascript

What is the difference between these methods on handling input changes and when should i use one or the other?:
const handleChange = () => {
console.log("hello")
}
// first method
<input
onChange={() => handleChange()}
[...]
// second method
<input
onChange={() => handleChange}
[...]
// third method
<input
onChange={handleChange}
[...]
// fourth method
<input
onChange={handleChange()}
[...]
Note that I'm using functional components.

The first method is the kost correct, except you need the default onChange's arg, which is a native event, so for example: (e) => { e.preventDefault() }. With this method you can assign a function's execution with some non-default args.
The second one is totally incorrect.
The third one would call our function with the default argument(s), so here it's the same as my corrected method one.
The fouth one is also incorrect, as it would execute your function at the moment of React binding it to the element.

first method <input onChange={() => handleChange()} [...]
second method <input onChange={() => handleChange} [...]
fourth method <input onChange={handleChange()} [...]
These all do not use anywhere as per ECMA 6.
if we have only one onChange event which is your third option then we have to just pass our event as a name no need to pass the event object to in the argument as a parameter.
// third method
<input onChange={handleChange} [...]
but, if we need to pass our event as a argument then go for this option as per below[we have more than one event onClick or onchange]:
e.g. <input onChange={(event) => handleChange(event); otherEvent(); }}
and then we can access our handle change value using this method
const handleChange = (event) => {
console.log("hello", event)
}

Use of functions depend on requirement.
First is used when you need to pass something like - event, data for some operation.
Second way isn't correct way.
Third way is recommended to use
<input
onChange={handleChange} />
Fourth way isn't recommended to use because it will call on every page load.

By default, onChange handover change event as a parameter of onChangeHandler.
First Method is used to use custom parameters:
onChange={() => handleChange(customParam1, customParam2)}:
The second method is used to return the handle change function whenever an onChange event occurs.
onChange={() => handleChange} equals to onChange={function handleChange(e){[...]}}
Third method is used to use default onChange event as parameter of handleChange function:
onChange={handleChange} equals to onChange={(e) => handleChange(e)}
The last method is used to use return value of handleChange as onChangeHandler:
onChange={handleChange()} equals to onChange={(e) => handleChange()(e)}
The 2nd and 4th are similar as they use the return value as onChange handler.
Btw, 2nd method is the best one for onChange handling.
You should use the 2nd method as your primary method.
Thank you.

Related

React handleChange methods event.target.value vs. (event, newValue)?

What is the difference between:
const handleChange = (event) => {
setValue(event.target.value);
};
and
const handleChange = (event, newValue) => {
setValue(newValue);
};
? The first seems to work in some cases, and the second in others.
First of all, I want to tell you that you are just passing a function for events like onChange or onClick, right? So, this is simple. We can pass any parameters to a function based on our needs. For those events, we basically use the following syntaxes:
const handleChange = (event) => {
setValue(event.target.value);
};
Here handle change is just a normal function, so it is not required that you only have to pass event as your parameter. It can be anything that you require to process that function. For the above use case, you needed input value that's why you passed the event object as the first param. But, maybe sometimes you will need extra data to work with that function. For example, you have multiple inputs, like below. You can add such inputs by clicking plus icon. And we might be storing data in an array of objects [{trait_type:'', value:''},{trait_type:'',value:''}], each array element represents a pair of those input. It will be efficient to use a change handler that accepts both (event and index) of input as params.
What is the main point is you are just passing functions to those events, and you can pass 0 or more parameters. It is not the rule that you have to pass Event for all event handlers. Yeah, sometimes you might require an Event object to stop propagating the event. Hope this explanation will help you. Make changes as you needed and best suited for you. Thank you.

React event target value in onChange

What is the difference between
onChange={({ target: { value } }) => setInsertedTitle(value)}
and
onChange={setInsertedTitle}
When should one or another be used?
Using onChange={({ target: { value } }) => setInsertedTitle(value)} you are passing the current target value as a parameter.
It is because onChange generates an Event, and you access the value by event.target.value ...
event: {
target: {
value: "string"
}
}
On the other hand, when you use the function like in onChange={setInsertedTitle}, it receives the event.
You can see it here: https://codesandbox.io/s/compassionate-fast-krrib?file=/src/App.js
Look at what each does and spot the differences:
onChange={({ target: { value } }) => setInsertedTitle(value)}
Creates an arrow function (let's call it func)
Whenever onChange/func gets called, e.g. func(event):
It uses destructuring to set value to the value of event.target.value
It calls setInsertedTitle with value (therefore event.target.value)
In the other case:
onChange={setInsertedTitle}
When onChange gets called with event, we directly call setInsertedTitle with event.
Therefore the main difference is whether it passes event.target.value or just event.
The first one passes a function to onChange that, when called, will get the value of the target element of the event (this is probably an input element, so target will be that input element) and pass that value to setInsertedTitle. So when the event occurs, setInsertedTitle gets called with a string (the value of the input).
The second one will directly pass setInsertedTitle to onChange. When the event occurs, setInsertedTitle will get called with an event object rather than the value of the input.
For the avoidance of doubt: The first one is correct, the second one is incorrect. (Even if you wanted to have an event object in your state data — which you almost certainly don't — you can't just keep the one you're passed; you're not allowed to keep them as they get reused [I think that's going to change at some point].)

Why Must I Put An Arrow Function Instead of Just the Return Value in React Event Handler?

I have looked over a bit of textbooks and blog posts but most seem just mumble through without a clear explanation...
in a event handler in React, I was told to write,
onChange = {() => setValue(someValue)}
onChange = {() => this.props.someFunction(someValue)}
I just don't understand why I cannot simply write something like
onChange = {setValue(someValue)}
onChange = {this.props.someFunction(someValue)}
since in my understanding setValue is a function by itself already, "() =>" look absolutely redundant to me.
On the other hand, if the event is defined within a class then I am allowed to write like this
onChange = {this.someFunction}
How come I am not required to write as aarow function in this case then? Like
onChange = {() => this.someFunction}
Isn't that double standard???
Because this:
this.someFunction
and this:
this.someFunction()
are two very different things. The first one is a reference to the function itself, whereas the second one executes the function and evaluates to its return value.
So when you do this:
onChange = {this.someFunction}
you're telling it:
When the value changes, execute this.someFunction and pass it the change event.
But when you do this:
onChange = {this.someFunction()}
you're telling it:
Execute this.someFunction right now, passing it nothing. When the value changes, execute whatever this.someFunction returned (which probably isn't an executable function) and pass it the change event.
The purpose of the arrow function is to create a function where one doesn't already exist. So if you just have a simple function reference, pass it:
onChange = {this.someFunction}
But suppose you want to do two things, not just call that one function. In that case you'd wrap those two things in an anonymous function:
onChange = {(e) => {
this.someFunction(e);
somethingElse();
}}
Or even simpler, suppose you have a simple function reference but it exepcts the new changed value instead of the change event itself:
onChange = {(e) => this.someFunction(e.target.event)}
Basically you create a function if you don't already have one which does what you want.

React unwanted submit on every character inputed

Everytime I enter a character in my input textfield, it automatically presses the submit button attached to it.
I would like to enter all the characters in the input textfield before it submits.
It's this part that is causing a problem:
<input type="text" ref={this.input} onChange={this.handleChange} />
<input type="submit" className="text-success col-offset-3" onClick={console.log("clicked")} value="Add Stock"/>
For example, it will console.log "clicked" everytime I enter a character in the input textfield without me actually clicking the button
Does any one of you guys know why?
Your passing in console.log() so every time the page re-renders the function gets called. As your calling it by passing it in like that.
You need to pass it in like this:
onClick={() => console.log("Clicked")}
<input type="submit" className="text-success col-offset-3" onClick={console.log("clicked")} value="Add Stock"/>
This is calling the console.log function every time the component is rendered. It's probably why you think the form is being submitted every time you type something. You should do something like this:
<input type="submit" className="text-success col-offset-3" onClick={() => console.log("clicked")} value="Add Stock"/>
You can find some more information in the React docs: Handling Events.
Explanation:
The reason why you do this, is that in React you don't include the parenthesis on your events. So in html you would do:
Regular HTML:
<button onclick="myFunc()">Button</button>
But in React you need to do:
JSX:
<button onClick={myFunc}>Button</button>
(Note that in class components you may need to use this.myFunc).
If you use the parenthesis in React, you're actually just calling the myFunc function when that piece of code is run:
This is wrong:
<button onClick={myFunc()}>Button</button>
Now, what happens if the function needs to take some parameters? i.e. what you need myFunc to be called with some number like 123 for example? This is covered in the docs (see Passing Arguments to Event Handlers
), there are two or three ways to go about this:
Create an auxiliary function that calls the function you want to call:
Kind of messy, but I'm including this since it's a valid alternative:
// Somewhere else in your component...
myAuxFunc = () => {
myFunc(123)
}
// Inside your render...
<button onClick={this.myAuxFunc}>Button</button>
Use an arrow function:
This is somewhat similar to creating an auxiliary function. Actually we are doing the same thing, we are creating a function that calls the function we're actually interested in, only that we're not naming it (it's an anonymous arrow function) and we're creating it on the spot:
<button onClick={() => myFunc(123)}>Button</button>
This can be tricky, but it is essentially the same as the first alternative I mentioned. I'm telling react that when the button is clicked, I want the following function to be called: () => myFunc(123). It's a function that takes no parameters, and when it is called, it will call myFunc(123).
(Class components) Use the bind function to bind the this keyword:
This is useful in class components when you want to call functions defined in your components so I'm including this here for completeness. It's not actually useful when you want to call a function like console.log.
<button onClick={this.myFunc.bind(this, 123)}>Button</button>

Using <input oninput= ... with current value in textbox

I have an simple HTML input tag inside my React component, defined thusly:
<input type="text" onInput={(value) => {
search(value);
return value;
}}/>
By using oninput, I am hoping to invoke the search method, with the current value in the textbox as an argument, whenever the value in in the textbox is changed. The search method is defined in the same component thusly:
const search = _.debounce((value) => {
doSomething(value);
}, 500);
When I debug in Chrome Dev Tools, I see that value has the following value, instead of the current value in the textbox:
[[Handler]]: Object
[[Target]] : SyntheticEvent
[[IsRevoked]] : false
What am I doing wrong? How can I call search and provide it the current value in the textbox as an argument? Online examples show oninput being used like <input type="text" oninput="myFunction()">, but they don't show how to pass the value in your textbox as input to the function called on the oninput event.
The parameter of your onInput function is a JavaScript Event object. To extract the value of it, you have to first bind the value of the input box to something:
<input
type="text"
value={this.state.value}
onInput={this.handleSearch}
/>
And then in your component methods, extract this value with event.target, which allows you to look at the DOM elements properties (we want the value property):
handleSearch(event) {
this.setState({value: event.target.value});
this.search(event.target.value); // Or wherever your search method is
}
EDIT: renamed search => handleSearch to avoid confusion :)

Categories