3

I was reading about "Lifting State Up" in React JS documentation and there is something I am not very clear about. The codepen can be found here: https://codepen.io/valscion/pen/jBNjja?editors=0010

In the TemperatureInput component, the onTemperatureChange event handler calls the handleCelsiusChange, but the latter contains a parameter of temperature. How are we passing this parameter? There is no argument passed in the onTemperatureChange. What am I missing here?

Hope someone can help me understand this.

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>
    );
  }
}
2
  • It would be better if you share code of TemperatureInput component so that I can see what are you passing in onTemperatureChange. Commented Jun 7, 2017 at 4:31
  • I updated the question Commented Jun 7, 2017 at 4:41

3 Answers 3

1

Let's look at the TemperatureInput component first. When its input element fires a change event, this is handled by handleChange(e) (declared within the TemperatureInput component). You'll notice that it then calls this.props.onTemperatureChange with the parameter e.target.value (this is the value attribute of the input element).

Where does this.props.onTemperatureChange come from? It's set by the parent component Calculator that instantiates it. Looking at the render method of the Calculator component, you'll notice that the onTemperatureChange prop for each TemperatureInput instance is set to this.handle[Cel/Far]Change (both methods declared within the Calculator component).

So when the TemperatureInput component calls this.props.onTemperatureChange, it is in fact calling the handle[Cel/Far]Change method of the Calculator component.

Sign up to request clarification or add additional context in comments.

Comments

0

Here to the TemperatureInput component you are passing the function (it acts like a pointer).

This is passed from Calculator to TemperatureInput component.

Now we see, our function handleCelsiusChange requires one argument, Therefore when we call onTemperatureChange function inside TemperatureInput component, we must be passing some variable there.

As you can see below code you are passing the parameter to the function call.

 handleChange(e) {
    this.props.onTemperatureChange(e.target.value);
  }

This where we are passing the argument to the function from TemperatureInput component

Comments

0

In the TemperatureInput component, the onTemperatureChange event handler calls the handleCelsiusChange...

This assumption is incorrect. You are passing a reference to the function object this.handleCelsiusChange to the attribute onTemperatureChange in the render function.

This function object is then used by calling it in TemperatureInput class.

this.props.onTemperatureChange(e.target.value)

If it were to call the handleCelciusChange in the JSX, the render would look like:

    <TemperatureInput
      scale="c"
      temperature={celsius}
      onTemperatureChange={this.handleCelsiusChange(some_value)} />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.