Home > other >  How to render conditional content in react
How to render conditional content in react

Time:02-08

I am trying to figure out how to tweak this boilerplate repo, so that on the index page, I can either render one page for the logged in user, or another for anyone else. The boilerplate index renders the same page, always, but adds an extra bit to it if there is an authenticated user.

Currently, when I try:

return (
    <Box>
      <Head>
        <title>title</title>
      </Head>
      <div>
      <Limiter pt={20} minH="calc(100vh - 65px)">
        <Center flexDir="column">
        {!me  &&
            <Box textStyle='h1' mb={8} mt={8} textAlign="center" >
              <HomeLandingPage />
            </Box> 
        } 
        {me && router.replace("/dashboard")}
        
        </Center>
      </Limiter>
      </div>
    </Box>
  )

I get no errors in the terminal, but I get this error in the browser:

Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

If I remove the second condition (ie me is true), I can render the HomeLandingPage without an error, but I just get an empty page if !me is false. The same is not true if I delete the !me condition and just try to render the logged in user page. I get the same error as when I try to use both alternatives.

I don't know where to put an array to deal with this. Some posts about this error resolved their problems by putting everything inside a div tag. I'm using ChakraUI, which calls a div a Box, which I am using, but I tried adding extra divs at each level of the home page to try and find a version that works - none did.

I was trying to rely on the login redirect on successful authentication handler, which has:

  const onSubmit = (data: LoginInput) => {
    return form.handler(() => login({ variables: { data } }), {
      onSuccess: async (data) => {
        await fetch("/api/login", {
          method: "post",
          body: JSON.stringify({ [LOGIN_TOKEN_KEY]: data.login.token }),
        })
        client.writeQuery<MeQuery>({ query: MeDocument, data: { me: data.login.user } })
        router.replace(redirect || "/dashboard")
        // router.replace('/dashboard')
        // router.replace('/profile/index')
        // console.log(redirect, REDIRECT_PATH)
        
      },
    })
  }

I expected this handler to redirect to the /dashboard on successful login - but it does not.

If I remove the me handler from the index.tsx page, I just get an empty page page when I authenticate, and I can then add /dashboard to the browser url to navigate to the page that I am trying to redirect to on successful authentication.

My first line of enquiry to solve this is why I can't have a redirect in the home page if me is true.

Are there any clues that could inspire the direction of my research into next steps?

CodePudding user response:

You're trying to render a function which returns a promise. Instead, put it outside of the render code, so that it can redirect you to the desired location. Your routing will take care of rendering the dashboard component once redirected.

if (me) {
  router.replace("/dashboard");
  return <LoadingSpinner />; // or some indication that we're redirecting
}

// this will only be rendered for a guest user
return (
  <Box>
    <Head>
      <title>title</title>
    </Head>
    <div>
    <Limiter pt={20} minH="calc(100vh - 65px)">
      <Center flexDir="column">
        <Box textStyle='h1' mb={8} mt={8} textAlign="center" >
          <HomeLandingPage />
        </Box>      
      </Center>
    </Limiter>
    </div>
  </Box>
)
  •  Tags:  
  • Related