Component flashing the wrong variant before switching to the correct one

Hi Plasmic team! I am running into an error when I am conditionally rendering a component based on state where the component flashes the wrong variant before switching to the corrected variant based on the conditional. How can I render the variant without flashing other variants first?

interface AuthenticationButtonSigninProps
extends DefaultAuthenticationButtonSigninProps {}
function AuthenticationButtonSignin(props: AuthenticationButtonSigninProps) {
  const modalState = useAppSelector(selectModal);
  const dispatch = useAppDispatch();
  const [authenticated, setAuthenticated] = useState(false);
  const { user } = useUser();
  const router = useRouter();
  useEffect(() => {
    if (user) {
      setAuthenticated(true);
    }
    if (!user) {
      setAuthenticated(false);
    }
  }, [user]);
    async function signOut() {
    try {
      router.push("/");
        await Auth.signOut();
    } catch (error) {
        console.log('error signing out: ', error);
    }
  }
if(authenticated){
  return <PlasmicAuthenticationButtonSignin
  authenticated={true}
  root={{
    props: {
      onClick: () => (
        signOut()
        
      )
    }
  }}
/>
}else{
  return <PlasmicAuthenticationButtonSignin
  authenticated={false}
  root={{
    props: {      
      onClick: () => (
        dispatch(openSignIn())
    )}
  }}
/>}}
export default AuthenticationButtonSignin;

Hey @ideological_sloth, there are two types of “hidden” elements in Plasmic studio: “not rendered” and “hidden”. If you use the latter it should get rid of the flashing because it uses CSS media-queries instead of JavaScript logic to decide what to render.

Ok thanks! @parliamentary_trout

Oh, sorry, I read your post before the edit and misunderstood it. I think your code shouldn’t really cause flashing, but can you try replacing the if statement with something like:

return <PlasmicAuthenticationButtonSignin
  authenticated={authenticated}
  root={{
    props: {
      onClick: () => (
        authenticated ? signOut() : dispatch(openSignIn())
      )
    }
  }}
/>;

Ok this cleans things up a lot thanks!

Hi, I am still getting the flashing of the wrong variant between changing pages even when set to hidden. Any other thought on how to fix this? Maybe preloading?

Hi @ideological_sloth - Plasmic components should only be rendering the variants you pass in. If you are seeing a flash, that is probably because the state is momentarily something other than what you would expect it to be.

When you are seeing a flash, do you specifically mean you’re seeing “not authenticated” flash before “authenticated”? I think that is because of the useEffect that reads user and sets authenticated. That means there will be a flash of time where user is set but authenticated is not set (even though you expect them to be either both set or both not-set).

You don’t really need authenticated as its own state, you can just do something like:

const authenticated = !!user;

Ok that makes sense. I changed the useState Hook as per below and I am still getting a flash of the unauthenticated variant first

function AuthenticationButtonSignup(props: AuthenticationButtonSignupProps) {
  const modalState = useAppSelector(selectModal);
  const dispatch = useAppDispatch();
  //const [authenticated, setAuthenticated] = useState(false);
  const { user } = useUser();
  const authenticated = !!user;

    return <PlasmicAuthenticationButtonSignup 
    authenticated={authenticated}
    root={{
      props: {
        id: "signupButton",
        onClick: () => (
          dispatch(openSignUp())
        )
      }
    }}
    />;
}

Also, thank you for the quick response and the help on this!

@yang, and @tiago, thanks for your support. We can close this one.

FYI - When using React Context for state management, all child components are re-rendered by default. We were able to solve this by editing the Global Variant for Authentication for ALL Components in the Plasmic Studio.

Cheers!