3

I was playing with ReacJS. I noticed a thing- In case of Class Component during re-rendering class variable's updated value is updated in screen like:

import React, { Component } from "react";

class Temp extends Component {
  constructor(props) {
    super(props);
    this.count = 0;
    this.state = {
      foo: 0,
    };
  }
  render() {
    return (
      <button
        onClick={() => {
          this.setState({ foo: this.state.foo + 1 });
          this.count++;
        }}
      >
        {this.count} - {this.state.foo}
      </button>
    );
  }
}

export default Temp;

But in case of function component the updated value of the ordinary variable is not updated in the screen during re-rendering.

import React, { useRef, useState } from "react";

const RefComponent = () => {
  const [stateNumber, setStateNumber] = useState(0);
  let refVar = 0;

  function incrementAndDelayedLogging() {
    setStateNumber(stateNumber + 1);
    refVar++;
  }

  return (
    <div>
      <button onClick={incrementAndDelayedLogging}>Click</button>
      <h4>state: {stateNumber}</h4>
      <h4>refVar: {refVar}</h4>
    </div>
  );
};

export default RefComponent;


Is this how React was implemented or I'm messing around something? I'm curious to know about it. Thanks

3
  • Every time functional RefComponent is rendered (called) it executes let refVar = 0; so refVar is created every time you render. You could do: const refVar = React.useRef(0); then refVar.current++ and <h4>refVar: {refVar.current}</h4> Commented Apr 19, 2020 at 19:22
  • Thanks. Yeah I'm familiar with useRef, actually I'm not searching for the way to solve this rather i just wanted to know why it happens in this way. But i appreciate your replies. Another query, doesn't class component gets called like the function component? Commented Apr 19, 2020 at 20:40
  • No, a functional component is just a function returning jsx, a class component is a class (in JavaScript also just a function but called as new MyClass()). So name in class component is an instance property (also called member), and name in functional component is just a variable you set every time it is called. Commented Apr 19, 2020 at 21:49

2 Answers 2

3

Functional components in React don't have instances, so things like class or instance variables don't necessarily make sense; like others have pointed out in the comments here, React will render (call) functional components and "reset" any local variables that are not explicitly state. Behavior like instance variables for functional components are achieved with useRef.

From the docs:

The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.

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

Comments

0

This is a consequence of functional components.

Think about it like this: Each time a state var is updated or a prop is updated your function gets called again. All variable declaration will happen again (states are a special case), so let refVar = 0; gets called again.

If you need that variable to live for multiple renders you'll need to declare it in a context that survives re-renders.

You have at least 2 ways of achieving this

  • declare a state for it with useState
  • declare it at the module level, but know all your instances of RefComponent will share the same instance

4 Comments

You could do useRef, then you can change it without the component re rendering just as an instance variable of a class would behave.
Thanks. Yeah I'm familiar with useRef, actually I'm not searching for the way to solve this rather i just wanted to know why it happens in this way. But I appreciate your replies. Another query, doesn't class component gets called like the function component?
@Mateen It seems you're not familiar with constructor functions (JS doesn't have classes but protype and constructor functions). A class component is a constructor function with prototype and is used like new Component().render() and a functional component is just called jsx=Component(props)
Sorry, I do know that Classes are just syntactic sugar over how we dealt with prototype chain of function, and later with new keyword. But I failed to match that here. What I asked all was about mechanism of React's rendering. Now I got it. Thanks.

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.