混音:一些不同的东西
大约三年前,我从 Web 开发爱好转向了 Web 开发工作。我之所以能找到这份工作的信心,部分原因在于我在这里公开学习开发的经验,所以,本着同样的理念,我决定尝试学习Remix。
在开始之前,我应该声明一下,我是一名前端开发者,后端经验很少。我之前用过 NodeJS,也涉猎过 PHP 和 Perl。我也知道 NextJS 很流行,甚至可能是更好的入门选择,但我决定先看看 Remix 能提供什么。以后我可能会考虑 NextJS,看看情况如何。
至少一开始我会先按照Remix 网站上的博客教程来做。如果我觉得有点道理,我可能会停止学习,看看最终会怎样。好了,废话不多说,我们开始吧。
设置
首先,让我们创建一个工作空间。我创建了一个名为 的新文件夹remix-server
(虽然名称并不重要),然后打开了 VSCode。在终端中,我输入了npx create-remix@latest
并按照说明进行操作。
Need to install the following packages:
create-remix@latest
Ok to proceed? (y)
R E M I X
💿 Welcome to Remix! Let’s get you set up with a new project.
? Where would you like to create your app? .
? Where do you want to deploy? Choose Remix if you’re unsure, it’s easy to change deployment targets. Remix App Server
? TypeScript or JavaScript? TypeScript
? Do you want me to run `npm install`? Yes
> postinstall
> remix setup node
Successfully setup Remix for node.
当它询问我想要在哪里创建应用程序时,我刚才使用了.
这个名称,如果我想创建一个新目录,我可以像这里一样写入目录名称.\my-dir
。
您可能还注意到我使用的是 Typescript 而不是 JavaScript,这是因为我正在学习 Typescript,但如果您想使用 JS,那没问题,我确信我们编写的大部分内容都是可转移的。
一旦 NPM 完成其工作,我就可以运行npm run dev
并查看服务器。
制定路线
如果我们查看已创建的文件,您会注意到有一个名为 的文件夹app
,其中还有一个名为 的文件夹,routes
该文件夹内有一个名为 的文件index.tsx
,该tsx
文件是 TypeScript React 文件,您可能会看到jsx
它与 JS 等效。我查看了索引文件,发现它是一个看起来很正常的 React 文件,其中包含我们刚刚制作的演示页面的内容。
在教程中继续阅读,我们发现它要求我们修改索引文件并创建新的路线,所以让我们这样做,但也要稍微偏离脚本,以确保我们知道发生了什么。
我计划修改索引文件,使其包含一个,Link
就像教程中提到的那样。之后,我会新建一个名为 test 的目录,并在其中放入一个名为 index 的文件和另一个名为 inner 的文件。这样,我就能访问localhost:3000
,localhost:3000/test
并localhost:3000/test/inner
查看我的三个文件了。
/* base level index */
import { Link } from "remix";
export default function Index() {
return (
<>
<h1>This is a test</h1>
<Link to="/test">Test page</Link>
</>
);
}
/* Index file inside '/test' */
import { Link } from "remix";
export default function TestIndex() {
return (
<>
<h1>This is a test</h1>
<Link to="/test/inner">Test inner</Link>
</>
);
}
/* File called inner inside '/test' */
export default function Inner() {
return (
<>
<h1>You found me!!</h1>
</>
);
}
你知道它的工作原理吗?路由文件夹内的任何目录似乎都会变成路由,如果路由中包含索引文件,则直接访问该路由即可访问该文件,其他文件也可以通过在 URL 中路由后输入其名称来访问。我相信以后还会遇到比这更复杂的情况,但目前看来,理解这些已经足够了。
让我们继续本教程。
获取数据
这部分我觉得有点乱,它一开始就让你把所有代码都放在一个文件中,然后告诉你这不是最佳实践,并让你重构它。另外,在 TypeScript 版本中,当接口工作正常时,它会让你使用 Type。我会告诉你我做了哪些不同的事情,虽然最终不会有太大的不同,但我觉得这样可以减少困惑。
useLoaderData 钩子
首先,我们需要使用一个名为useLoaderData
“导入”的钩子remix
,就像我们之前在 link 中做的那样。这还需要我们从正在使用的文件中导出一个useLoaderData
名为 loader 的函数。最佳实践是使用这个函数async
,因为它允许我们等待数据加载。loader 函数应该以我们想要在 React 文件中使用的格式返回数据。
import { useLoaderData } from "remix";
export const loader = async () => {
return 'hello world';
};
export default function Posts() {
const loadedData = useLoaderData();
return (
<>
<h1>Posts!</h1>
{loadedData}
</>
);
}
上面的代码片段将打印“hello world”,就像函数返回的loadedData
那样loader
。
现在,如果我们想从中获取更复杂的数据,loader
最好创建一个包含该函数的新文件,然后将该函数导入到我们的 React 文件中,并在loader
函数内部使用它。由于我们不希望这个新文件包含路由,因此让我们回到上app
一级,并创建一个名为“loaders”的新文件夹,在这里我们将创建一个名为的文件posts.ts
。
export interface Post {
slug: string;
title: string;
}
export const getPosts = (): Post[] => {
return [
{
slug: "my-first-post",
title: "My First Post",
},
{
slug: "90s-mixtape",
title: "A Mixtape I Made Just For You",
},
];
};
此文件包含一个描述返回数据的接口getPosts
。我们还包含一个名为 的函数getPosts
,它只返回我们想要获取的“数据”。将来,它可能会包含一些数据库调用或其他内容,但现在我们先保持简单。接口和函数都已导出,以便我们可以在帖子索引文件中使用它们。
import { Link, useLoaderData } from "remix";
import { getPosts, Post } from "~/loaders/post";
export const loader = async () => {
return getPosts();
};
export default function Posts() {
const posts = useLoaderData<Post[]>();
return (
<>
<h1>Posts!</h1>
{posts.map((post) => (
<li key={post.slug}>
<Link to={post.slug}>{post.title}</Link>
</li>
))}
</>
);
}
如你所见,我们导入了接口和函数。接口允许我们修改useLoaderData
函数,这样一来,IDE 就能自动补全posts
const is 和 s 数组,Post
就像接口描述的那样。
动态路由
要添加动态路由,请在 routes 目录中创建一个新文件。该文件必须以 开头,$
但名称的其余部分可以随意命名。在 remix 给出的示例中,他们使用了 ,slug
因此我们也照做。
当你这样做的时候,一些神奇的事情发生了。之前的加载函数可以看到你输入的 URL 并对其进行处理,但让我们退一步来看看这里到底发生了什么。
事实证明,加载器函数总是会传递一个我们可以使用的对象。该对象包含一个request
对象,一个context
(对我来说是未定义的),以及一个params
对象。请求是服务器接收的完整请求,包括完整的 URL、方法(在本例中为 GET),甚至还有一个以后可能会用到的查询。现在我们对加载器函数的功能有了简单的了解,让我们继续。
我们关心的 URL 部分存储在加载器参数的 params 部分中,在我们的例子中,它被称为文件名称减去$
, 。slug
export const loader: LoaderFunction = async ({params}) => {
return params.slug;
};
LoaderFunction
是我们从 remix 导入的一种类型,以使 typescript 能够正常工作。
加载数据
我们可以使用像 fs 这样的常规 NodeJS 工具从文件系统加载文件。本教程指导我们在 app 目录下创建一些可以加载的 Markdown 文件。
使用fs
我们可以获取所有文件名的列表,还可以使用 加载位于 md 中的帖子标题parseFrontMatter
。这些数据可以结构化,以替换旧的静态帖子数组。
现在我们需要一个新的函数,它可以从动态路由中获取 slug,并打开文件并将其显示md
为 HTML。我们再次使用fs
来加载文件,然后使用marked
将其转换md
为 HTML。我们调用这个函数getPost
,并将其导入到我们的$slug
文件中,就完成了。
回顾
回顾一下,
- 使用 npm 启动一个新项目
- 制定了一些自定义路线
- 加载一些数据来构建动态内容列表
- 读取
md
文件并将其转换为 html - 在动态路由中显示该 html
感觉内容很多,但又不算太多。教程才进行到一半,但这篇文章已经很长了,所以感觉现在是时候停下来了。
感谢您的阅读,这真的意义重大。请随时留言,哪怕只是告诉我哪里做错了,或者哪里可以改进。
如果您想在 Dev 之外与我联系,这里有我的推特和领英,来打个招呼吧😊。
文章来源:https://dev.to/link2twenty/remix-something- Different-1i06