Common mistakes when using React - Why the screen value does not change
Tags: react, javascript, webdev, beginners
Published: 2023-03-05 08:46:48

I guarantee that 99% of people who are new to React have been puzzled by the following phenomenon.

```js
const Counter = () => {
  let counter = 0;
  return <button onClick={() => counter++}>{counter}</button>;
};
```

Why isn't the counter going up on the screen when you press the button?

Do you know why counter doesn't go up when you press the button after you have used useState?

### So, how does React work fundamentally?
```js
/* html */
<body>
  <div id="app"></div>
</body>;

/* js */
const $app = document.getElementById("app");
const jsx = <div>Hello</div>;
ReactDom.render(jsx, $app);
```

After receiving the JSX.Element, it is parsed into a pure HtmlElement, specified a specific HtmlElement, and renders the parsed value `<div>Hello</div>` under that HtmlElement.

To help understand it, here's what it looks like in Vanilla JS:
```js
const $app = document.getElementById("app");
const $divElement = doucment.createElement("div");
$divElement.innerText = "Hello";
$app.appendChild($divElement);
```
Getting back on track, what will happen if you run the following code?
```js
const $app = document.getElementById("app");
let jsx = <div>Hello</div>;
ReactDom.render(jsx, $app);
setTimeout(() => {
  jsx = <div>Nice to meet you</div>;
}, 3000); // Changes the value of jsx to <div>Nice to meet you</div> after 3 seconds
```
The answer is that the text displayed on the screen does not change from `"Hello"` to `"Nice to meet you."` The reason is the same as the counter example we started with.

### Because...
It's because we didn't call `ReactDom.render()` again!
```js
const $app = document.getElementById("app");
let jsx = <div>Hello</div>;
ReactDom.render(jsx, $app);
setTimeout(() => {
  jsx = <div>Nice to meet you</div>; // Changes the value of jsx to <div>Nice to meet you</div>
  ReactDom.render(jsx, $app); // Applies the changed value under $app again.
}, 3000);
```
If you call `ReactDom.render()` again in the timeout callback, the text on the screen will finally change to `"Nice to meet you."`

Now let's apply this to the counter example...
```js
const Counter = () => {
  let counter = 0;
  return <button onClick={() => counter++}>{counter}</button>;
};
```
#### How can we apply it here?
Are you struggling with how to apply `ReactDom.Render`?

We don't actually need to import the `ReactDom.Render` function here.
```js
const Counter = () => {
  const [counter, setCounter] = useState(0);
  return (
    <button onClick={() => setCounter((prev) => prev + 1)}>{counter}</button>
  );
};
const $app = document.getElementById("app");
ReactDom.render(<Clicker />, $app);
```
The `setState` function of the array returned by `useState` (in this case, setCounter) calls `ReactDom.Render` internally every time it is executed.

### In summary...

The reason why the counter doesn't increment when the button is clicked in the initial Counter example is simple.

It's because we haven't actually **manipulated** the HtmlElement.

We need to parse the JSXElement into an actual HtmlElement using `ReactDom.render` and then render it on the `DOM` to see the value change on the screen.