NextJS中的客户端渲染和服务端渲染

前言

为什么会想着探究这个呢?因为我在学习的过程中发现:在next中默认是"use server"也就是如果使用服务端的话是不需要标明的,只有客户端才需要标明"use client",但是在我去掉代码中的"use server"后会报错code:500(完整代码如下),于是就有了本文章。

"use server";

import connectDB from "@/lib/db";
import { User } from "@/models/User";
import { redirect } from "next/navigation";
import { hash } from "bcryptjs";
import { CredentialsSignin } from "next-auth";
import { signIn } from "@/auth";

const login = async (formData: FormData) => {
  const email = formData.get("email") as string;
  const password = formData.get("password") as string;

  try {
    await signIn("credentials", {
      redirect: false,
      callbackUrl: "/",
      email,
      password,
    });
  } catch (error) {
    const someError = error as CredentialsSignin;
    return someError.cause;
  }
  redirect("/");
};

const register = async (formData: FormData) => {
  const firstName = formData.get("firstname") as string;
  const lastName = formData.get("lastname") as string;
  const email = formData.get("email") as string;
  const password = formData.get("password") as string;

  if (!firstName || !lastName || !email || !password) {
    throw new Error("Please fill all fields");
  }

  await connectDB();

  // existing user
  const existingUser = await User.findOne({ email });
  if (existingUser) throw new Error("User already exists");

  const hashedPassword = await hash(password, 12);

  await User.create({ firstName, lastName, email, password: hashedPassword });
  console.log(`User created successfully 🥂`);
  redirect("/login");
};

const fetchAllUsers = async () => {
  await connectDB();
  const users = await User.find({});
  return users;
};

export { register, login, fetchAllUsers };

省流

这里就直接放我的结论:

  • "use client":通常为react组件,使用了react hook。
  • "use server":通常为CRUD、数据库处理等数据相关内容。
  • 存在react hook的页面必须实用"use client"。
  • 服务端渲染和客户端渲染各有利弊,两者是平等的渲染页面的方式,并不是某些地方必须用到客户端渲染而某些地方必须用到服务端渲染,是可选而非必须的。所以nextjs中区分客户端渲染和服务端渲染实际上是让我们考虑如何结合两者的优点来对页面渲染进行优化。

ps:以上为本人个人观点,如有错误欢迎评论区指正。 

正文

Reactjs 带有三个发布通道。第一个是稳定的金丝雀,最后一个是实验性的

Reactjs 指令是 React 18 中引入的新功能,当前的 reactjs 指令是金丝雀版本的一部分。

Reactjs 指令是 Reactjs 服务器组件的一部分。有些人将指令称为服务器操作。

服务器操作和 reactjs 指令都是相同的功能;不要混淆。

Reactjs 的指令是一组与 React Server 打包器兼容的指令。

Reactjs 的指令指导如何有效地捆绑和组织 React 组件。

大多数情况下,当你使用React.js服务器组件时,你可以在文件顶部使用 reactjs 指令。

'use client'; // define reactjs directive

import React, { useState } from 'react';

export const Counter = () => {
  const [count, setCount] = useState(0);
  
   // rest of code 

 );
};

但你也可以在 JSX 函数或组件中使用 reactjs 指令。

export default function Page() {
 
  async function CreateAndaddToCart(formData: FormData) {
    
    'use server'
 
    // mutate data

    // revalidate cache

  }
 
  return <form action={create}>...</form>
}

为了更好地理解,react 指令有两种类型。

  1. 'use client'
  2. 'use server'

use client:

use client reactjs 指令运行或在客户端执行组件。你可以使用 React 钩子,如 useState、useEffect 等。

'use client'

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>+</button>
      <p>{count}</p>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  );
};

export default Counter;

use server

使用 serve react 指令在 serve 端运行或执行组件。您可以使用服务器组件处理数据提取 (CURD) 功能。

'use serve'

export async function Posts() {
  
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  return posts.map((post) => <Post post={post} />) // return JSX serve side 

}

注意事项

  1. 不能对同一文件使用 and 操作。'use client''use server'
  2. 使用 use 服务器操作时,您不能使用像 useState、useEffect、useRef 等客户端钩子。
  3. 每个服务组件都在服务端呈现,而不是在客户端呈现。

 最后附上我参考过的两篇文章:

 Next.js 服务端组件和客户端组件区别及使用场景

浅谈服务端渲染(SSR) 与使用场景 - 掘金 (juejin.cn)

 

 

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值