Home > Blockchain >  Button component is getting rendered twice every time
Button component is getting rendered twice every time

Time:11-15

I tried to increment the count whenever i click the button. When click the button it is getting rendered twice. But it should be render only once.

Here is my code https://codesandbox.io/s/async-pine-3z2ty3?file=/src/App.js

import { useCallback, useMemo, useState } from "react";
import Button from "./Button";

export default function App() {
  const [count, setCount] = useState(0);
  const [count1, setCount1] = useState(0);

  const handleClick = useCallback(() => {
    setCount(count   1);
  }, [count]);

  const MyButton1 = useMemo(
    () => <Button handleClick={handleClick} title="Increment Count" />,
    [handleClick]
  );
  const MyButton2 = useMemo(
    () => (
      <Button handleClick={() => setCount1(count1   1)} title="Click here" />
    ),
    [count1]
  );
  return (
    <div className="App">
      <div>count : {count}</div>
      {MyButton1}
      <div>count1 : {count1}</div>
      {MyButton2}
    </div>
  );
}
import React from "react";

const Button = React.memo(({ handleClick, title }) => {
  console.log(title);
  return <button onClick={handleClick}>{title}</button>;
});

export default Button;

CodePudding user response:

Problem

  1. Your handleClick function changes count
  2. If count changes new handleClick is created
  3. If handleClick changes you create new <Button>

Solution

  1. Remove redundant useMemos
  2. Pass a function to setCount
  3. Remove dependency from useCallback
export default function App() {
  const [count, setCount] = useState(0);
  const [count1, setCount1] = useState(0);

  const handleClick = useCallback(() => {
    setCount((count) => count   1);
  }, []);

  return (
    <div className="App">
      <div>count : {count}</div>
      <Button handleClick={handleClick} title="Increment Count" />
    </div>
  );
}

Now your component will be rendered once at the beginning and never again

If you want to have two buttons, you have to have two callbacks

export default function App() {
  const [count, setCount] = useState(0);
  const [count1, setCount1] = useState(0);

  const handleClick = useCallback(() => {
    setCount((count) => count   1);
  }, []);

  const handleClick1 = useCallback(() => {
    setCount1((count) => count   1);
  }, []);

  return (
    <div className="App">
      <div>count : {count}</div>
      <Button handleClick={handleClick} title="Increment Count" />
      <div>count : {count}</div>
      <Button handleClick={handleClick1} title="Click here" />
    </div>
  );
}

sandbox

CodePudding user response:

Remove <StrictMode></StrictMode> from your index.js file

  • Related