React JS event handler arguments
I read about "Going Up" in the React JS documentation and I don't quite understand something. The codepen can be found here: https://codepen.io/valscion/pen/jBNjja?editors=0010
In the TemperatureInput component, the onTemperatureChange event handler calls handleCelsiusChange, but the latter contains the temperature parameter. How do we pass this parameter? There are no arguments in onTemperatureChange. What am I missing here?
Hope someone can help me figure this out.
class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
this.props.onTemperatureChange(e.target.value);
}
render() {
const temperature = this.props.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}
class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {temperature: '', scale: 'c'};
}
handleCelsiusChange(temperature) {
this.setState({scale: 'c', temperature});
}
handleFahrenheitChange(temperature) {
this.setState({scale: 'f', temperature});
}
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
return (
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} />
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} />
<BoilingVerdict
celsius={parseFloat(celsius)} />
</div>
);
}
}
source to share
Here you pass a function to the TemperatureInput component (it acts like a pointer).
This is passed from the Calculator to TemperatureInput component.
We can now see that our handleCelsiusChange function requires one argument. Therefore, when we call the TemperatureChange function inside the TemperatureInput component, we must pass some variable there.
As you can see below, you are passing a parameter to a function call.
handleChange(e) {
this.props.onTemperatureChange(e.target.value);
}
This is where we pass the argument to the function from the TemperatureInput component
source to share
In the TemperatureInput component, the onTemperatureChange event handler calls handleCelsiusChange ...
This assumption is incorrect. You are passing a reference to a function object this.handleCelsiusChange
to an attribute onTemperatureChange
in the function render
.
This functional object is then used by calling it in the class TemperatureInput
.
this.props.onTemperatureChange(e.target.value)
If it were calling handleCelciusChange in JSX render
it would look like this:
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange(some_value)} />
source to share
Let's look at the TemperatureInput component first. When its input element fires a change event, it is handled handleChange(e)
(declared in the TemperatureInput component). You will notice that then it calls this.props.onTemperatureChange
with a parameter e.target.value
(this is the value attribute of the input element).
Where from this.props.onTemperatureChange
? It is installed by the parent Calculator component that creates it. If you look at the render method of the Calculator component, you will notice that the parameter onTemperatureChange
for each TemperatureInput instance is set to this.handle[Cel/Far]Change
(both methods are declared in the Calculator component).
So when the TemperatureInput component calls this.props.onTemperatureChange
, it actually calls the handle[Cel/Far]Change
Calculator component method .
source to share