The parent logic is still processing while the component is already rendering props.children

Struggling with implementing auth logic in my next.js project as I try to teach myself the framework.

I have a specific page, protected/profile, that should only be accessible to logged-in users. To achieve this, I am fetching user data in getServerSideProps and then passing it to a child component called Protected. Protected is responsible for checking if the user is authenticated before rendering the profile page by returning props.children.

If a user tries to access the profile page without being logged in, they should be redirected to /

However, it seems like the profile component renders the page regardless and does not wait for the Protected logic to complete. When attempting to access the profile while logged out, an error occurs stating that user.user_metadata cannot be found instead of redirecting as expected.

The console logs show:

Profile log
protected.tsx:7 Protected log
protected.tsx:17 Protected: Has user
const Profile = ({user} : {user: User}) => {
    console.log("Profile log");
    return (
        <Protected user={user}>
            <h1>This is Profile</h1>
            <h1>Hello, {user.user_metadata.full_name}!</h1>
            <p> Your email : {user.email}</p>
        </Protected>
    )
}

export const getServerSideProps: GetServerSideProps = async ({req}) => {
    const {user} = await supabaseClient.auth.api.getUserByCookie(req);
    return { props: {user: user}}
}

export default Profile;
export default function Protected(props: {user: User, children}){
    console.log("Protected log");
    if(!props.user){
        console.log("Protected: Null user");
        return {
            redirect: {
                destination: "/",
                permanent: false
            }
        }
    }
    console.log("Protected: Has user");
    return props.children;
}

Answer №1

First and foremost, it's important to note that returning a redirect object from a React component is not possible. If you intend to utilize a redirect object, you'll need to return it from the getServerSideProps function or implement custom logic using useRouter or similar methods.

Additionally, it's advisable to treat the user parameter as optional since it may not always be present in your code:

const Profile = ({ user }: { user?: User }) => {
    console.log("Profile log");
    return (
        <Protected user={user}>
            <h1>This is Profile</h1>
            <h1>Hello, {user.user_metadata.full_name}!</h1>
            <p> Your email : {user.email}</p>
        </Protected>
    )
}

If you encounter a Typescript error indicating that you are trying to access properties of an undefined object, consider creating a separate component dedicated to handling user-related logic:

const Profile = ({ user }: { user?: User }) => {
    console.log("Profile log");
    return (
        <Protected user={user}>
            <UserProfile user={user} />
        </Protected>
    )
}

Alternatively, modify the Protected component to accept children as functions:

const Profile = ({ user }: { user?: User }) => {
  console.log('Profile log');
  return (
    <Protected user={user}>
      {() => (
        <>
          <h1>This is Profile</h1>
          <h1>Hello, {user.user_metadata.full_name}!</h1>
          <p> Your email : {user.email}</p>
        </>
      )}
    </Protected>
  );
};

The implementation of Protected might look something like this:

export function Protected(props) {
  if(!props.user){
    // Implement alternative redirect logic, as the current method with objects will not work
  }
  // Note the invocation of children here
  return props.children();
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unleash the Power of Connecting Web Browsers with Local Filesystems (

I'm currently utilizing a powerful tool called VoTT, which can be found at the following link: https://github.com/microsoft/VoTT. Impressive enough, this tool is crafted using react/redux. While this tool functions flawlessly as a web application, on ...

Troubleshooting: Next.js application deployment on Azure Web App encountering file discrepancies

I'm currently facing an issue while attempting to deploy a next.js (with typescript) application on Azure using Bitbucket pipelines. As part of my pipeline process, I build the next.js app with the following build configuration: // next.config.js /** ...

React Typescript: The specified argument type cannot be assigned to the parameter type

Creating a Check Box Button React component has resulted in an error related to setRSelected(1) and setRSelected(2)... const [cSelected, setCSelected] = useState([]); const [rSelected, setRSelected] = useState(); const onCheckboxBtnClick = (selected ...

Tips for implementing React on Azure Web App with the Azure App Service extension in Visual Studio Code

I attempted to troubleshoot by following numerous questions and blogs online, but I was unsuccessful. I have developed a basic React application with this particular configuration: https://i.stack.imgur.com/FNlmR.png It functions properly locally. After ...

Change the color of specific elements in an SVG using React

Can I change the dynamic primary color from ReactJS to a specific class in an SVG file? If yes, how can it be done? Error.svg <!-- Generator: Adobe Illustrator 26.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1&qu ...

Adding the location of the onClick event to the hook - a step-by-step guide

Here is the code I am working with: import { MapContainer, TileLayer } from "react-leaflet"; import React, { useState } from 'react'; export default function App() { const [positionLat, setPositionLat] = useState(null); ...

How can we style the <a> link once it has been downloaded?

Is there a way to change the color of a download link after it has been clicked on? I've attempted using the visited attribute, but it only seems to work with regular links and not with download documents: Appreciate any help ...

Incorporate HTML and React JS dynamically through AJAX response

Is there a way to activate React JS after inserting AJAX response into a page? The page consists of only a div and script tag as shown below; <div data-react-class="example" data-react-props="{}" data-react-cache-id="example-0& ...

deploying both my backend and frontend on firebase platform

My test project is created using React JS for the frontend and Node JS for the backend, organized in their respective folders: -frontend (folder) ---- React JS -backend (folder) ---- Express JS It works perfectly locally, but now I want to publish it ...

Creating ReactJS powered Single Page Application (SPA)

I am working on a login screen that leads to a home page with Bootstrap navigation upon successful login. The navigation includes various links. Can anyone advise me on: The proper usage and configuration of 'browserouter' How to control the v ...

The Typescript error occurs when trying to assign a 'string' type to a 'SetStateAction<null>'

For my project, I am delving into creating a global context using TypeScript. As a newcomer to TypeScript, I found a helpful guide in this blog post (). Despite following the outlined steps, I keep encountering an error message saying "Type 'string&ap ...

What is the correct way to use setInterval in a React component's constructor?

I'm trying to set an interval when the main component renders. I attempted to do this in the constructor like so: constructor(props) { super(props); this.props.fetchUserInfo(); this.props.fetchProducts(); setInterval(console.log(&a ...

What is the hierarchy for displaying elements depending on the props?

I have developed a search input component that includes an icon which I want to reposition (either on the left or right side) depending on different scenarios. This input is part of a bootstrap input-group, so modifying the order of elements within my di ...

Guide on building a multi-page application using Vue or React

I find myself a bit confused when it comes to single-page applications versus multi-page applications. While I am aware of the difference between the two, I am struggling with creating a MPA specifically. Up until now, I have built various apps using Rea ...

Ensuring a child element fills the height of its parent container in React Material-UI

Currently, I am in the process of constructing a React Dashboard using MUI. The layout consists of an AppBar, a drawer, and a content area contained within a box (Please correct me if this approach is incorrect)... https://i.stack.imgur.com/jeJBO.png Unf ...

Locating the DataGrid Component in Material-UI v5: A Guide on Installing DataGrid in React

After updating material-ui/core to version 5.0.0-beta.1 and material-ui/lab to version 5.0.0-alpha.30, I am unable to find the DataGrid component. It does not seem to be included in either material-ui/core or material-ui/lab. Additionally, the documentat ...

Getting the value from the object that holds the Provider/Consumer using React's Context API

Below is a demonstration using the Context API object with a library called 'react-singleton-context'. Check it out here. In my Menu.js file, I have the code snippet console.log(useSharedDataContext()). This displays an object containing Consume ...

Leveraging NextJS for Advanced Server-Side Rendering with Seamless Integration of React Query in the Front

I have implemented React Query in the following manner: const { data, isSuccess, isLoading } = useQuery(['myQuery', myParams], async () => { return myAjaxCall(myParams); }, { cacheTime: 0 }); The results are then passed into a custom ...

Using a variable obtained from React redux useSelector in the dependency array of useCallback leads to an endless cycle of re-render

I have a list called topics that I retrieve using useSelector. I am using this list in a callback function named updateXXX, and including it in the dependencies array of useCallback is causing infinite rendering. Can someone provide some suggestions on how ...

Setting the port for Next.js on PM2 involves configuring the ecosystem file in the project

I am currently working on a standard next js application and have the following scripts in my package.json file. "scripts": { "dev": "next dev", "build": "next build", "start": " ...