Is Remix the future of React framework?
Remix is an edge native, full-stack JavaScript framework for building modern, fast, and resilient user experiences. It unifies the client and server with web standards so you can think less about code and more about your product.
— Ryan Florence https://remix.run/blog/remix-vs-next
Like Next.js by Vercel, Remix is React framework used for server-side rendering (SSR), the data will be rendered on the server side and delivered to the user. This is just for trying to build a project using Remix, I do not recommend but I will tell you what the benefits of Using Remix are.
Remix is like an embed 1 or more components into the parent component, this one will reduce your loading time. And Remix has an alternative to handle an error, if you have an error in a component, the component will fail to render or show an error message, but will not break the entire page. No need to create by yourself, Remix has error boundaries, this one is pretty cool if happens in production, the user will not be locked out for the entire page.
And Remix will give you built-in transitions, Remix will handle all loading states, just give Remix the component that you want to show when the app is loading. This is much simpler than others React framework because other framework needs other libraries to handle this part, like Recoil or Redux.
Besides having many benefits, Remix also has disadvantages, like Remix doesn’t have a big community compared to Next.js. This can make you confused when you face a problem that you can’t find the solution to, nor you can’t post a thread on forums and wait for others to reply. Routing in Remix will make you confused, the nested route is a mess if you don’t understand, and you should have an effort to learn how to do with the nested routers in Remix.
I will start with how to create a Remix project using weather API.
npx create-remix@latest remix-weather-api
Just continue with what the command said. If they ask you to type y
so type it to continue. But when they ask you “Where do you want to deploy?”, just choose Remix App Server
. Then you can be asked to choose Javascript or Typescript, just choose what do you comfortable with.
Before you start to code, install axios
and dotenv
first.
npm i axios dotenv
After that update your package.json
to config your Remix project
"dev": "node -r dotenv/config node_modules/.bin/remix dev"
The config above is to enable your environment variables for your projects. Create a .env
file to store variables
API_KEY={your_api_key}
API_URL=https://api.openweathermap.org/data/2.5/weather
Run npm run dev
to run a live view of your Remix project. Then you will show it like this.
Update a root.tsx
file like this.
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
useCatch,
} from '@remix-run/react';interface IDocument {
title?: string;
children?: React.ReactNode;
}const App = () => (
<Document>
<Outlet />
</Document>
);export default App;export const ErrorBoundary = ({ error }: { error: Error }) => (
<Document title="Error!">
<div>
<h1>There was an error</h1>
<p>{error.message}</p>
<hr />
<p>
Hey, developer, you should replace this with what you want your users to
see.
</p>
</div>
</Document>
);export function CatchBoundary() {
let caught = useCatch();let message;
switch (caught.status) {
case 401:
message = (
<p>
Oops! Looks like you tried to visit a page that you do not have access
to.
</p>
);
break;
case 404:
message = (
<p>Oops! Looks like you tried to visit a page that does not exist.</p>
);
break;default:
throw new Error(caught.data || caught.statusText);
}return (
<Document title={`${caught.status} ${caught.statusText}`}>
<h1>
{caught.status}: {caught.statusText}
</h1>
{message}
</Document>
);
}const Document = ({ children, title }: IDocument) => (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
{title ? <title>{title}</title> : null}
<Meta />
<Links />
</head>
<body>
{children}
<ScrollRestoration />
<Scripts />
{process.env.NODE_ENV === 'development' && <LiveReload />}
</body>
</html>
);
Then create a form for fetching the weather on a index.tsx
file inside the router folder. Give a form method get
and give an input
component to append to the URL when the form is submitted.
const Index = () => (
<div>
<form action="/weather" method="get">
City: <input type="text" name="city" />
<input type="submit" value="Fetch weather" />
</form>
</div>
);export default Index;
Now we create a new file weather.tsx
in the routes
folder.
import { Outlet } from 'react-router';const Weather = () => (
<>
<h1>Remix Weather App</h1>
<Outlet />
</>
);export default Weather;
If you realized the code above has a Outlet
component, Outlet
will look for the weather folder inside the routes folder, and will embed the component inside the main page. This is what nested routes in Remix be implemented.
Now create a file to get the data from the URL, using a GET request, we should return the data, so the data will render on the screen.
import axios from 'axios';
import { useLoaderData } from '@remix-run/react';
import { redirect } from '@remix-run/node';interface ILoader {
request: {
url: string | URL;
};
}export const loader = async ({ request }: ILoader) => {
try {
const url = new URL(request.url);
const search = new URLSearchParams(url.search);
if (!search.get('city')) return redirect('/');
const city = search.get('city');
const res = await axios.get(`${process.env.API_URL}?q=${city}&appid=${process.env.API_KEY}&units=metric`); return { city, type: res.data.weather[0].main, temp: res.data.main.temp };
} catch (err) {
redirect('/');
return err;
}
};const Index = () => {
const data = useLoaderData(); return (
<div>
<h1>{data.city}</h1>
<h2>{data.type}</h2>
<h3>Temperature: {data.temp} °C</h3>
</div>
);
};export default Index;
Now you can see your Remix project can run well.
You can explore more here
Thank you