I am using the next.js
new functionality to render content using SSR
, I am making component async
as docs
says.
So this is my simple page component
export default async function Home() {
const res = await fetch("http://localhost:3000/api/get-quotes");
const quotes = await res.json();
return (
<main className={styles.main}>
<h1>Hello Visrut</h1>
<div>
<span>Total quotes: {quotes.length}</span>
</div>
</main>
)
}
I have authenticated
and non-authenticated
routes in my application, what I am doing to separate them in _app.tsx
// _app.tsx
interface AppProps {
Component: React.ElementType;
pageProps: Record<string, unknown>;
}
const App: React.FC<AppProps> = ({ Component, pageProps }) => {
const router = useRouter();
if (router.pathname.includes("home")) {
return <Home />; // Error: 'Home' can't be used as a JSX component, Its return type Promise<Home> is not a valid JSX component.
}
return (
<AuthContextProvider>
<Navbar />
<Head />
<Component {...pageProps} />
<Footer />
</AuthContextProvider>
)
};
export default App;
I want to render the Home
component which does not require authentication, it seems like I can’t just directly put it as children also because of the async
keyword.
I am also getting this error on the browser while directly rendering async
component into other normal components in next.js
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.
2
Answers
Move your async code into
getServerSideProps
function and pass the response into yourHome
component as PropsNext 12
Reference: https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props
Next 13
You have some concept issues in your code
You cannot have async components like that, the components must be sync functions, to fix this you have some ways to do it
Using useEffect:
You can your fetch calls inside an effect that handles these asynchronous issues, just like this:
Using the SSR from Next look at https://nextjs.org/docs/basic-features/data-fetching/overview here you can see some options to fetch the data before render the page, that is great, an example here:
That will fix the issue you mentioned, but you also have a concept issue with the
_app
file, the way you want to restrict the navigation, it looks like you want the layout (navbar, footer, etc) to only render when it’s not home, so that would be something like this:However, this only restricts the visual that it shows according to each route, here you are not really validating if you have an active session, but hey, I hope it helps you!