Dhruvil21_04
Dhruvil21_04

Reputation: 2189

How to show only message when the page has loaded instead of flickering text - React Hooks

I've seen different questions related to display message on page loading but in none of them there was example in which function was getting called inside useEffect itself.

Problem:

Anyways, moving to the problem, I'm getting flickering text which changes from "Unauthorized Access" to "Authorized" atleast couple of times (my assumption is due to state change) and so on which doesn't look good from User experience perspective.

What I expect?

Is there a way to only show "Unauthorized Access"/"Authorized" message without flickering text? enter image description here

const User = () => {
  const [type, setType] = useState(0);
  const [error, setError] = useState("");
  const [isloading, setIsLoading] = useState(true);
  const isCancelled = useRef(false);

  const getUserType = async () => {
    const response = await fetch("/API_ROUTE");
    const { type, error } = await response.json();
    if (!response.ok || error) {
      if (!isCancelled.current) setError(error);
      // console.log("failure", error);
    } else {
      // console.log("success", type);
      if (!isCancelled.current) setType(type);
    }
  };

  useEffect(() => {
    console.log("mounted1");
    getUserType();
    setIsLoading(false);

    return () => {
      isCancelled.current = true;
    };
  }, []);

  return (
    <h1>
      {isloading
        ? "Loading..."
        : type !== 2
        ? "Unauthorized Access"
        : "Authorized"}
    </h1>
  );
};

Upvotes: 0

Views: 36

Answers (2)

ichigolas
ichigolas

Reputation: 7725

You are not waiting for async function getUserType to finish before setting isLoading to false:

getUserType(); // this is asynchronous, you should await it.
setIsLoading(false); // You set `isLoading` to `false` before the actual fetching has finished

A simple solution would be to call setIsLoading(false) within getUserType, after fetching the data.

Upvotes: 1

radovix
radovix

Reputation: 3177

You should probably update your isLoading flag after proper type has been set.

useEffect(() => {
   console.log("mounted1");
   getUserType();

   return () => {
     isCancelled.current = true;
   };
}, []);

useEffect(() => {
   setIsLoading(false);
}, [type, error]);

Upvotes: 1

Related Questions