首页与我联系

使用 React 和 Next.js 做一个简单的博客网站(下)

By 前端达人
Published in 4-React
August 21, 2022
1 min read
使用 React 和 Next.js 做一个简单的博客网站(下)

大家好,在《动手练一练,使用 React 和 Next.js 做一个简单的博客网站(上)》和 《动手练一练,使用 React 和 Next.js 做一个简单的博客网站(中)》这两篇文章里,我们一起完成了一个基于MakeDown 文档的博客网站,了解了如何基于文件生成动态路由,Static Generation 相关方法的使用,本篇文章,我们将学习如何使用服务端渲染技术以及客户端渲染相结合的内容,最后在和大家聊聊如何编译项目、部署站点。

一、使用服务端渲染(Server-side Rendering)

服务端渲染(SSR)发生在每次页面请求时,其相关内容逻辑比如JS的数据请求都交由服务端处理完成后,在将内容呈现给访问的用户,因此通过此技术可以做一些复杂的业务逻辑,比如每个用户登录成功后,呈现不同的页面内容。

在《动手练一练,使用 React 和 Next.js 做一个简单的博客网站(中)》这篇文章里,我们使用了getStaticProps() 这个方法在项目编译时(build)生成 MD 相关的静态界面。如果要使用服务端渲染,我们可以使用 getServerSideProps() 函数,在页面请求时执行此函数逻辑,完成服务端的数据渲染。

这里我们要实现一个简单的功能,在 about.js 这个界面,去请求一个笑话网站的API服务(https://official-joke-api.appspot.com/jokes/random),在这个页面,我们通过服务端的形式去请求,然后将数据呈现给用户,好了,我们开始动手实现吧。

1、我们现在 /pages/about.js 页面里添加 getServerSideProps() 函数,这个方法里我们去调用一个服务端的数据接口,这里我们使用 node-fetch 模块,获取完数据后,通过 props 返回组件的属性中(请看第2点的相关代码),示例代码如下:

// fetch a random joke (generated on every reqest)
export async function getServerSideProps() {
  const res = await fetch('https://official-joke-api.appspot.com/jokes/random');
  return {
    props: {
      data: await res.json()
    }
  }
}

2、接下来我们来编写组件JSX 的部分,接收 getServerSideProps() 的数据,示例代码如下

export default function About({ data }) {
  return (
    <Layout hero="keyboard.jpg">
      <Head>
        <title>About us</title>
        <meta name="description" content="What we do." />
      </Head>
      <h1>About us</h1>
      <p>Some information about us.</p>
      <h2>A random { data.type } joke</h2>
      <p className="setup">{ data.setup }...</p>
      <p className="punchline">{ data.punchline }</p>
      <style jsx>{`
        .setup { font-weight: bold; }
        .punchline { font-style: italic; }
      `}</style>
    </Layout>
  );
}

你可能注意到了,上述代码使用了 styled JSX 语法添加 CSS 样式。

到这里,服务端渲染的功能就完成了,我们通过 npm run dev 重启下 next.js 服务器,在浏览器上

点击 http://localhost:3000/about 预览,就会看到如下图所示的界面:

ssr0.jpeg

二、客户端渲染(Client-side Rendering),实现暗黑浏览模式

Next.js 会在编译的时机(build time)或者 或页面请求时在服务端完成 React 组件的渲染逻辑,但是有时候我们不要这么做,有些功能完全可以交给用户端浏览器处理,也是官方说道的客户端激活 (client-side hydration 不知道怎么翻译,暂且这么叫吧,借用vue相关文档的翻译)比如这个功能我们要实现暗黑和白天模式的切换,这里我们就可以用到 React.useEffect() 这个钩子处理函数。

由于在服务端,有个细节需要注意,在服务端没有 window 这个顶层对象的,如下段所示,将会运行失败。

// THIS WILL FAIL!
const [href, setHref] = React.useState(window.location.href);

为了修复这个问题,我们可以将初始值赋值null。

1、首先我们新建个 components/themetoggle.js 暗黑和白天模式切换的组件,这里使用 useEffect() 这个钩子函数实现其逻辑功能,示例代码如下:

import React from 'react';
import styles from './themetoggle.module.scss';
export default function Themetoggle() {
  const
    toggleStore = 'themeToggle',
    [theme, setTheme] = React.useState(null);
  React.useEffect(() => {
    if (!theme) {
      setTheme(
        localStorage.getItem(toggleStore) ||
        (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
      );
    }
    if (theme) {
      const body = document.body;
      body.classList.remove('dark', 'light');
      body.classList.add(theme);
      localStorage.setItem(toggleStore, theme);
    }
  }, [theme])
  return (
    <button
      onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
      className={ styles.themetoggle + ' ' + styles[theme] }
      title="switch theme"
    />
  );
}

由于服务端无法访问客户端模式的初始值,我们先初始化为null,然后当组件成功加载至客户端时,我们使用 useEffect() 这个钩子函数进行黑暗和白天模式的逻辑处理。你可能注意到为此组件,我单独引用了一个 CSS 文件,具体源码,你可以在文末阅读原文,在本项目的完整源码中找到。

2、最后,我们将此组件添加至 components/header.js 文件中 Header 组件中,示例代码如下:

import Navmenu from './navmenu';
import Themetoggle from './themetoggle';
import Link from 'next/link';
export default function Header({ hero }) {
  hero = '/images/' + (hero || 'orb.jpg');
  return (
    <header>
      <p className="logo">...</p>
      <Themetoggle />
      <Navmenu />
      <figure>...</figure>
    </header>
  );
}

接下来,重新运行 Next.js 服务,每个页面都添加了黑暗与白天切换的模式功能 ,如下图所示:

themetoggle.gif

三、编译发布网站

到这里为止,一个完整的简单博客网站到这里就介绍完了,如果你想在生产环境部署网站的话,先停在站点 Ctrl | Cmd + C , 然后运行如下命令

npm run build

编译完成后,你会发现的项目根目录里多了个 .next 目录,这个目录你可以部署到 Node.js 10 以上的服务器上。

你可以在此文件夹里运行 npm run start,在测试环境下去测试生成环境下的正式站点。

四、生成静态HTML页面

Next.js 允许你将现有的站点生成静态的 HTML 页面(除了需要服务端渲染的界面),如果你为页面定义了 getServerSideProps() 服务端渲染相关的函数,导出将会失败。

如下所示,需要按照命令的先后进行运行:

npx next build
npx next export

编译完成后,你将会在项目的根目录看到 out 这个文件夹,如下图所示:

2021-04-11_10.45.08.png

五、接下来你可以动手试一试

本文给大家展示了 Next.js 基础内容实现了博客的基础功能,接下来你可以继续完善,亲自动手试一试为博客网站提以下功能 :

  • 添加404页面配置
  • 实现博客文章列表页的分页功能
  • 添加文章标签功能
  • 添加 SSR 功能
  • 尝试从其他方式获取文章内容(服务端、wordpress等)

六、相关阅读

《动手练一练,使用 React 和 Next.js 做一个简单的博客网站(上)》

《动手练一练,使用 React 和 Next.js 做一个简单的博客网站(中)》

结束语

到这里,本案例就介绍完了,Next.js 是一个灵活的应用程序框架,可以帮助你构建任何类型的 web 项目,对于博客网站这类需求,很容易满足实现。

Next.js 这个框架已经很成熟,而且定期维护,如果你很熟悉 React 这个前端框架,选择 Next.js 构建站点将会是一个不错的选择。 前端达人公众号.jpg

注:本文属于原创文章,版权属于「前端达人」公众号及 qianduandaren.com 所有,未经授权,谢绝一切形式的转载


Tags

reactadvancedNext.js
Previous Article
「基础」关于 :is, :where 和 :has 新伪类选择器的介绍
前端达人

前端达人

专注前端知识分享

Table Of Contents

1
一、使用服务端渲染(Server-side Rendering)
2
二、客户端渲染(Client-side Rendering),实现暗黑浏览模式
3
三、编译发布网站
4
四、生成静态HTML页面
5
五、接下来你可以动手试一试
6
六、相关阅读
7
结束语

相关文章

「React Hooks 学习笔记」关于Custom Hooks 的使用介绍(八)
October 28, 2022
1 min

前端站点

VUE官网React官网TypeScript官网

公众号:前端达人

前端达人公众号