The `useLoaderData` hook
Frontend and backend code
Section titled “Frontend and backend code”In any given website, there are two main parts to the code that drives it:
-
Frontend code: This is the code that runs in the user’s browser. It’s written in JavaScript and is responsible for rendering the website and handling user interactions.
-
Backend code: This is the code that runs on the server. It’s written in a server-side language like Node.js, Python, or Ruby, and is responsible for fetching data from a database, processing it, and sending it to the frontend.
In a traditional website, the frontend and backend code are separate and communicate with each other using HTTP requests. The frontend code makes a request to the backend code, which processes the request and sends back a response.
In Remix, the frontend and backend code are combined into a single file called a route module. The file we have been working in - root.tsx
- is an example of a route module.
This file contains both the frontend code (React components) and the backend code needed to render a particular page.
So far, we have been working exclusively on the frontend code. So where is the backend code? Let’s take a look…
The loader
and action
functions
Section titled “The loader and action functions”Take another look at the app/root.tsx
file:
import { type LinksFunction } from '@remix-run/node'import Document from '~/components/shared-layout/Document'import { useNonce } from '~/utils/nonce-provider.ts'import rootLinkElements from '~/utils/providers/rootLinkElements'
export const links: LinksFunction = () => { return rootLinkElements}export { headers, meta } from './__root.client.tsx'export { action, loader } from './__root.server.tsx'
export default function App() { const nonce = useNonce()
return ( <Document nonce={nonce}> <div className="flex h-screen flex-col justify-between"> <div className="flex-1"> <main className="grid h-full place-items-center"> <h1 className="text-mega">Welcome to Epic News!</h1> </main> </div> </div> </Document> )}
You’ll notice that we are exporting two functions from this file: action
and loader
.
export { action, loader } from './__root.server.tsx'
These functions are responsible for fetching data from the server and processing it before it is sent to the frontend.
But where are these functions defined? The line highlighted above says that the action
and loader
functions are being exported somehow, but we don’t see them in this file. 🧐
That’s because they are defined in a completely separate file: __root.server.tsx
. We can communicate between two files in JavaScript using import
and export
statements.
If you are interested, open up the __root.server.tsx
file and take a look at the loader
function. You’ll see that it is responsible for fetching data from the server and sending it to the frontend.
We will be looking more closely at the loader
function in a later tutorial.
For now, we just need to get the data from the loader
function into the frontend component. Let’s see how we can do that…
Adding useLoaderData
to the App
component
Section titled “Adding useLoaderData to the App component”useLoaderData
is a custom React hook supplied for us by Remix.
Updating the import
statements
Section titled “Updating the import statements”Making sure you are still inside app/root.tsx
, let’s start by updating the import
statements at the top of the file.
Add the code highlighted in green to the end of your import
statements in app/root.tsx
:
import { type LinksFunction } from '@remix-run/node'import Document from '~/components/shared-layout/Document'import { useNonce } from '~/utils/nonce-provider.ts'import rootLinkElements from '~/utils/providers/rootLinkElements'import { useLoaderData } from '@remix-run/react'import ThemeSwitch from '~/components/shared-layout/ThemeSwitch'import { type loader } from './__root.server'import useTheme from './hooks/useTheme.tsx'
Next, carefully add the code highlighted in green below to the App
component function itself:
14 collapsed lines
import { type LinksFunction } from '@remix-run/node'import Document from '~/components/shared-layout/Document'import { useNonce } from '~/utils/nonce-provider.ts'import rootLinkElements from '~/utils/providers/rootLinkElements'import { useLoaderData } from '@remix-run/react'import ThemeSwitch from '~/components/shared-layout/ThemeSwitch'import { loader } from './__root.server'import useTheme from './hooks/useTheme.tsx'
export const links: LinksFunction = () => { return rootLinkElements}export { headers, meta } from './__root.client.tsx'export { action, loader } from './__root.server.tsx'
export default function App() { const data = useLoaderData<typeof loader>(); const nonce = useNonce(); const theme = useTheme()
return ( <Document nonce={nonce} theme={theme}> <div className="flex h-screen flex-col justify-between"> <div className="flex-1"> <main className="grid h-full place-items-center"> <h1 className="text-mega">Welcome to Epic News!</h1> </main> </div>
<div className="container flex justify-between pb-5"> <ThemeSwitch userPreference={data.requestInfo.userPrefs.theme} /> </div> </div> </Document> )}
Testing the light and dark mode toggle button
Section titled “Testing the light and dark mode toggle button”Save your changes, then head back to the browser. You should now be able to toggle the theme between light and dark mode by clicking the button:
🎉 Congratulations! 🎉
Section titled “🎉 Congratulations! 🎉”You now have a working light and dark mode toggle button in your Remix app! 🚀
Automatically organise imports in VS Code
Section titled “Automatically organise imports in VS Code”Finally, lets fix the yellow underlines that might still be showing under your new import
statements.
As mentioned earlier, VS Code is warning us that we haven’t used the values, variables and functions that we are importing yet.
Thankfully, VS Code provides us with a keyboard shortcut to automatically organise our imports in the correct order.
- Windows: SHIFT + ALT + O
- Mac: SHIFT + OPTION + O
Press this shortcut now to automatically organise your imports at the top of your file:
Remember to save your file after you have done this, and commit your changes to Git.
Support your explanations with screenshots and code snippets where necessary.
What’s next?
Section titled “What’s next?”In the next step, we will add a navbar and footer to the website to introduce navigation and improve user experience.