Next.js 垃圾课程 - 第 3 部分/共 3 部分
大家好,开发人员。
你周末过得还好吗?真心希望如此。🙏
我应该昨天就发布这最后一部分,很抱歉我来晚了,但终于,在经历了近三个月的寒冷和黑暗之后,我们这里终于有了几个小时的阳光照耀,所以我决定享受它。☀️
如果您是新来的,并且不知道Trash Course是什么意思,请检查👇:
提示:我没有放弃Next.js
或做任何事情。
但如果你一直关注到这里,请接受我所有的谢意。🏆 很高兴你能加入。
第 3/3 部分将涵盖哪些内容?🤩
- 静态资产、自定义页面标题和元数据
- 获取数据
- 动态路线
第 9 部分 - 静态资产、自定义页面标题和元数据
在 Web 应用中,我们可能经常使用静态资源(例如,图标、图片等)。Next.js
我们可以将它们放置在public
文件夹中来实现这一点。
我从网上抓取了一张Ash Ketchum 的图片作为示例,并将其放在公共文件夹 ( public/ash.png
) 中。我们将在组件中使用它作为我们的 logo Navbar
。
import Link from 'next/link';
import Image from 'next/image'; // we import it and use below as following
export const Navbar = () => {
return (
<nav>
<div className="brand">
{/** Here 👇 */}
<Image src="/ash.png" width={60} height={60} />
</div>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/dev/">Dev</Link>
</nav>
);
};
img
如果我们愿意,我们也可以使用经典标签: <img src="/ash.png" alt="ash ket" />
。
使用该Next.js Image
组件时需要考虑的一些要点如下:
- 我们需要明确指定它的
width
属性height
,否则会引发错误。 - 它会根据提供的属性自动使图像具有响应能力。
- 它利用了延迟加载设计模式。它只在需要渲染时才加载,例如,如果图像放在我们的页脚中,
Next.js
则只有当页面向下滚动到达页脚时才会加载它。
谈论将metadata
和添加customized title
到不同的页面,它可以像我们的以下示例一样简单Home
:
import Link from 'next/link';
import Head from 'next/head'; // We import the Next.js' Head component
export default function Home() {
return (
<>
{/** 👇👇👇 */}
<Head>
{/** Add the title and metadata for the page as shown below*/}
<title>Creep Home Page</title>
<meta name="keywords" content="next,random design,trash course" />
</Head>
{/** 👆👆👆 */}
<div className="container">
<h1>Hello Next.js</h1>
<div>
<Link href="/about">About</Link>
</div>
</div>
</>
);
}
记住,所有组件都只能用一个父元素包裹,否则会抛出“存在多个父元素”的错误。我使用了空标签,<></>
但也可以是React Fragment
、 a<div>
等等。
第 10 部分 - 获取数据 ⬇️ 💽
通常在应用程序中,我们获取的数据来自服务器端,例如数据库、Web 服务器等。
为了简单起见,我们从JSON API Placeholder获取一些模拟数据
在应用程序中,React
我们将使用useEffect
钩子获取数据,并在浏览器中发出请求。
它Next.js
略有不同,因为所有组件在到达浏览器时都会先进行预渲染。换句话说,我们需要提前获取数据,以便渲染后的组件在其模板中已经拥有这些数据。
这就是Next.js
'getStaticProps
函数发挥作用的地方。我将使用我们开发人员的主页 ( pages/dev/index.js
) 从 中获取数据https://jsonplaceholder.typicode.com/users
。
在我们的dev's index page
( pages/dev/index.js
) 中我们必须创建getStaticProps
函数和export
它。
export const getStaticProps = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
return { props: { users: data } };
};
⚠️不要在函数内编写任何getStaticProps
你期望在浏览器中运行的代码。⚠️
getStaticProps
它很特殊async function
,因为它在构建时运行。在这个函数中,我们添加了一个fetch requests
order,猜猜怎么着?它是为了获取我们想要在组件中渲染的数据。😉
我们从 API 端点获取的数据现在附加到{ users }
我们组件的 props() 上:
export default function Home({ users }) {
return (
<div>
<h1>Hello Devs</h1>
<ul>
{users.map((user) => (
<li key={user.id}>
<p>{user.username}</p>
<p>{user.email}</p>
</li>
))}
</ul>
<Button>Dev Button</Button>
</div>
);
}
就是这样。当然,这只是一个基本的实现,但作为起点,它运行得相当不错。
我也知道我应该添加一些样式,但这篇文章比我想象的要长,所以把它当作你的作业吧。🤜 🤛
第 11 部分 - 动态路线
如果我们从用户列表中获取数据后,点击特定用户时能够看到更多信息,那就太好了。实现这一点需要遵循一些步骤,但并不复杂。
我们需要:✏️
- 为每个用户生成动态路线,
- 创建一个组件来保存用户详细信息。
在文件夹内,pages/dev
我们将创建一个名为的文件,这样我们就可以在传递给组件的用户 ID 所在的位置设置[id].js
路由。/dev/id
id
您之前看到的语法[id]
是一种告知方式:“ - 嘿Next.js
,我将向该组件传递一些路由参数,因此请注意这一点。”。
我们的pages/dev/[id].js
组件最初看起来如下所示:
import React from 'react';
const UserInfo = () => {
return <div>Boom!</div>;
};
export default UserInfo;
现在,如果你访问路由http://localhost:3000/dev/2
,或者你作为路由参数传递的任何值,你应该会看到Boom!
渲染结果。它还不是动态的,所以让我们做一些修改来实现它。
- 让我们在列表中的每个用户中创建一个链接,以便当我们点击它时,我们使用它的 id 作为参数来获取他/她的个人数据。(
dev/index.js
)。
import { Button } from '../../components/Button';
import Link from 'next/link';
export const getStaticProps = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
return { props: { users: data } };
};
export default function Home({ users }) {
return (
<div>
<h1>Hello Devs</h1>
<ul>
{users.map((user) => (
{/** 👇👇👇 */}
<Link href={`/dev/${user.id}`} key={user.id}>
{/** LAZY styling 😅 🙈 */}
<li style={{ cursor: 'pointer' }}>
<p>{user.username}</p>
<p>{user.email}</p>
</li>
</Link>
))}
</ul>
<Button>Dev Button</Button>
</div>
);
}
最后,我们需要使用 调用端点user's id
来获取用户的个人信息。(pages/dev/[id].js
)。
export const getStaticPaths = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
const userPaths = data.map((user) => {
return { params: { id: user.id.toString() } };
});
return {
paths: userPaths,
fallback: false,
};
};
export const getStaticProps = async (context) => {
const userID = context.params.id;
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${userID}`
);
const data = await response.json();
return { props: { user: data } };
};
const UserInfo = ({ user }) => {
return (
<div>
<h2>User Info</h2>
<p>username: {user.username}</p>
<p>email: {user.email}</p>
<p>
address: {user.address.street} - {user.address.city}
</p>
<p>phone: {user.phone}</p>
<p>website: {user.website}</p>
</div>
);
};
export default UserInfo;
别害怕!那里面的大部分内容我们都已经熟悉了。我现在要尝试解释一下新概念。
- 功能
getStaticPaths
:✔️
export const getStaticPaths = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
const userPaths = data.map((user) => {
return { params: { id: user.id.toString() } };
});
return {
paths: userPaths,
fallback: false,
};
};
这也是一个特殊的函数。它获取数据并返回一个包含每个用户所有静态路径的数组,如下所示。
//...
const userPaths = data.map((user) => {
return { params: { id: user.id.toString() } };
});
return {
paths: userPaths,
fallback: false,
};
//...
请记住,所有页面都是在运行时构建的。想象一下它返回一个像这样的数组:[{ /dev/1 }, { /dev/2}, ... , { /dev/10 }]
。
该fallback: false
选项目前超出了范围,但如果删除它会引发错误。
- 功能
getStaticProps
(与以前相同但略有不同):✔️
export const getStaticProps = async (context) => {
const userID = context.params.id;
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${userID}`
);
const data = await response.json();
return { props: { user: data } };
};
它现在可以通过对象访问函数props
返回的内容。getStaticPaths
context
从这个对象可以访问每个用户的 ID,获取他们的个人信息并将其发送到UserInfo
组件(/pages/dev/[1].js
)。
好了,各位开发者们!看来我们成功了!🏅 🥇 🎉 🍾
确实,有很多东西需要探索,但我的目的只是做一个快速介绍Next.js
。
我计划发布一个额外的帖子来介绍api
文件夹(pages/api
)以及如何部署我们的应用程序,Vercel
但这很大程度上取决于我一周的工作安排,所以很遗憾,我无法承诺任何事情。😓
我希望你们享受我们在一起的时光并从中学到一些东西。😃如果您使用本系列的内容创建了自己的版本,请与我们分享。
我们很高兴看到您辛勤工作的成果。💪💎
非常感谢,大家注意安全!🙇♂️
鏂囩珷鏉ユ簮锛�https://dev.to/vinicius77/next-js-trash-course-part-3-3-3igc