menu

Questions & Answers

Input text causing unnecessary button rendering

I need to check the fields and i need to pass several properties to the button. String, Object, Array, Func and i need usestate be an object like example. Any solution to not cause re-rendering?

EDIT: I need to do a way that when the user fills in the input the button does not re-render.

EDIT 2: when I use the primitive type useState(string). And I make the comparison works , useState of type Object making comparison causes re-rendering on button:

code below does not cause re-rendering

  const [email, setEmail] = useState("");


  const validateFields = useCallback(() => {
    if (email === "") {
      alert("Empty e-mail.");

      return false;
    }

    return true;
  }, [email]);

code below does CAUSE re-rendering - (comparison with object)

 const [userData, setUserData] = useState({
    email: "",
    password: ""
  });

  const validateFields = useCallback(() => {
    if (userData.email === "") {
      alert("Empty e-mail.");

      return false;
    }

    return true;
  }, [userData]);

project link : https://codesandbox.io/s/tender-allen-tfklv8?file=/src/components/Button.js

import { useCallback, useState } from "react";
import Button from "./components/Button";
import "./styles.css";

export default function App() {
  const [userData, setUserData] = useState({
    email: "",
    password: ""
  });

  const validateFields = useCallback(() => {
    if (userData.email.trim() === "") {
      alert("Empty e-mail.");

      return false;
    }

    return true;
  }, [userData]);

  const handleAPI = useCallback(() => {
    if (validateFields()) {
      console.log("handleAPI");
    }
  }, [validateFields]);

  return (
    <div className="App">
      <input
        value={userData.email}
        onChange={(event) =>
          setUserData((prev) => ({
            ...prev,
            email: event.target.value
          }))
        }
      />
      <Button onClick={handleAPI} />
    </div>
  );
}



const Button = ({ onClick }) => {
  console.log("------------Button render---------------");

  return <button onClick={onClick}>BUTTON DEFAULT</button>;
};

export default memo(Button);
Comments:
2023-01-24 23:25:05
Your question isn't clear. React re-renders everything, unlike Vue, for example. Please revise to explain the problem that this re-rendering causes.
2023-01-24 23:25:05
Don't tell us down here. Revise your post. That doesn't answer my question anyway. It just restates the same thing.
Answers(1) :

If you're intending to use the validateData function when clicking on the button, there's no need for the handleAPI function to be within a useCallback hook that depends on validateData. Whenever you click on the button, the validateData function will be called and will validate the desired data with whatever value is currently in the userData state variable.

Comments:
2023-01-24 23:25:05
I put this useCallback to try to make the button not render when filling the input. I need to make a way for the button not to render when the user fills in the input.