Home > Net >  Any idea why my component isn't getting rendered in a conditional block, but renders standalone
Any idea why my component isn't getting rendered in a conditional block, but renders standalone

Time:10-17

I am trying to show a page only if the current user is logged in, else ask them to login. I am using firebase authentication to achieve this.

import Head from "next/head";
import { auth } from "../../components/firebase";
import { onAuthStateChanged } from "firebase/auth";
import Login from "../Login";
import AddProperty from "../../components/AddProperty";
const Properties = () => {
  const user = auth.currentUser;
  return (
    <>
      <Head>
        <title>Add Property</title>
        <meta name="keywords" content="web dev" />
      </Head>
      <h1>Add Property</h1>
      <p>Welcome to the add Property new</p>

      {onAuthStateChanged(auth, (user) => {
        if (user) {
          {
            <AddProperty />;
          }
        } else {
          <Login />;
        }
      })}
    </>
  );
};

export default Properties;

enter image description here

CodePudding user response:

onAuthStateChanged returns a function that unsubscribes the event handler registered for listening the firebase auth state. You need to store the authenticated user in a separate state and consume it in a JSX statement.

import Head from "next/head";
import { useEffect, useState } from 'react';
import { auth } from "../../components/firebase";
import { onAuthStateChanged } from "firebase/auth";
import Login from "../Login";
import AddProperty from "../../components/AddProperty";

const Properties = () => {

  const [user, setUser] = useState();
  
  useEffect(() => {
    const unsubscribe = onAuthStateChanged(
      auth.currentUser, 
      authUser => {
        setUser(authUser);
      }
    );
    
    return () => {
      unsubscribe();
    };
  }, [setUser]);

  return (
    <>
      <Head>
        <title>Add Property</title>
        <meta name="keywords" content="web dev" />
      </Head>
      <h1>Add Property</h1>
      <p>Welcome to the add Property new</p>
      {user ? (<AddProperty />) : (<Login />)}
    </>
  );
};

export default Properties;

CodePudding user response:

Not very familiar with Firebase but with a quick look at the docks, and being already familiar with React, here is my take.

Any data that effects the way React renders should be loaded in state, in your case, a useState() hook.

In Addition, I've basically ripped an example of what you're trying to do straight from the Firebase docs, and used it here. The static function is left outside the component, as it doesn't benefit from a re-render.

import Head from 'next/head';
import { useEffect, useState } from 'react';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
import Login from '../Login';
import AddProperty from '../../components/AddProperty';

const auth = getAuth();

const Properties = () => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    onAuthStateChanged(auth, user => {
      if (user) {
        setUser(user);
      } else {
        setUser(false);
      }
    });
  }, [setUser]);

  return (
    <>
      <Head>
        <title>Add Property</title>
        <meta name='keywords' content='web dev' />
      </Head>
      <h1>Add Property</h1>
      <p>Welcome to the add Property new</p>
      {user ? <AddProperty /> : <Login />}
    </>
  );
};

export default Properties;

Also I'm not sure of how often you want this user data pulled from a render, so this implementation runs onAuthStateChanged() on every render.

Hope this helps. Any issues, just comment and I'll try and help.

  • Related