jsartisan / frontend-challenges

FrontendChallenges is a collection of frontend interview questions and answers. It is designed to help you prepare for frontend interviews. It's free and open source.
https://frontend-challenges.com
27 stars 4 forks source link

React re-render bug #16

Closed jsartisan closed 7 months ago

jsartisan commented 7 months ago

Info

difficulty: medium
title: React re-render 
template: react
tags: react, performance

Question

We have 3 components: App at the top, which renders Counter, which renders BigCountNumber and a simple Decoration component. Due to how React works, when the state count changes, the Decoration is also re-rendering despite of the fact it is not dependent on the count state since it is not receiving count as prop. How can we avoid re-render of Decoration component?

Template

styles.css

html, body, #root {
  height: 100%;
}

body {
  font-family: sans-serif;
}

p {
  margin: 0;
}

main {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  align-items: center;
  padding-top: 5rem;
  height: 100%;
}

* {
  border: 1px solid green;
  animation: debug 1s forwards;
}

@keyframes debug {
  from {
    border-color: green;
  }
  to {
    border-color: transparent;
  }
}

App.jsx

import Counter from './Counter';

import React from 'react';

export default function App() {
 return <Counter />;
}

index.jsx

import React, { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./styles.css";

import App from "./App";

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

Counter.jsx

import React from 'react';

import Decoration from './Decoration';
import BigCountNumber from './BigCountNumber';

function Counter() {
  const [count, setCount] = React.useState(0);

  return (
    <main>
      <BigCountNumber count={count} />
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
      <Decoration  />
    </main>
  );
}

export default Counter;

Decoration.jsx

import React from 'react';

function Decoration() {
  return (
    <div className="decoration" key={Date.now()}>
      🚀
    </div>
  );
}

export default Decoration;

BigCountNumber.jsx

function BigCountNumber({ count }) {
  return (
    <p>
      <span className="prefix">Count:</span>
      {count}
    </p>
  );
}

export default BigCountNumber;
github-actions[bot] commented 7 months ago

17 - Pull Request updated.