Next.js SSR 页面关闭后的状态维护方案

Next.js SSR 页面关闭后的状态维护方案

在使用 Next.js 进行服务器端渲染(SSR)开发时,会遇到一种问题:当页面关闭或刷新后,原本已经存在的状态数据会被清空,导致用户体验不佳。

这个问题的解决方案是:通过客户端存储方式,将需要持久化的状态数据存储在用户的浏览器中,以便在后续用户再次访问页面时,能够恢复之前的状态。下面我们将详细介绍如何在 Next.js 中实现这个方案。

首先,我们需要使用一个叫做 js-cookie 的第三方库。该库可以在客户端中存储和读取 cookie,以实现持久化数据的存储。

客户端存储方案

下面是一个示例代码,用于实现在客户端中存储一个名为 userInfo 的 cookie:

import Cookies from 'js-cookie';

// 定义一个写入 cookie 的方法
const setUserInfo = (userInfo) => {
  Cookies.set('userInfo', userInfo);
};

// 定义一个读取 cookie 的方法
const getUserInfo = () => {
  return Cookies.getJSON('userInfo');
};

在组件中,可以使用该方法来存取对应的状态数据:

import { useEffect, useState } from 'react';

const UserInfo = () => {
  const [userInfo, setUserInfo] = useState(null);

  // 在组件渲染时,从 cookie 读取数据并更新组件状态
  useEffect(() => {
    setUserInfo(getUserInfo());
  }, []);

  // 在用户修改数据时,更新 cookie 数据
  const handleChange = (e) => {
    setUserInfo(e.target.value);
    setUserInfo(userInfo);
  };

  return (
    <div>
      <input value={userInfo} onChange={handleChange} />
    </div>
  );
};

服务器端存储方案

接下来我们来介绍一种服务器端存储方案,该方案比 cookie 更安全,但相应的实现成本也更高。

该方案需要使用到 Next.js 自带的 getInitialProps() 方法。由于该方法只能运行在服务端,因此所有的状态数据都需要先从服务端获取,再交由客户端存储。

以下是一个示例实现,假设我们需要在客户端中存储当前购物车的商品数量:

import { NextPageContext } from 'next';
import { useMemo, useState } from 'react';

interface Props {
  initialCount: number;
}

const StorageExample = ({ initialCount }: Props) => {
  const [count, setCount] = useState(initialCount);

  // 在组件渲染时获取状态数据
  const handleGetCount = () => {
    const count = Number(window.localStorage.getItem('cartCount'));
    if (!isNaN(count)) {
      setCount(count);
    }
  };

  // 在状态数据更新时,将数据更新到服务端
  const handleUpdateCount = () => {
    // 这里可以通过 Ajax 请求将数据更新到服务端
    window.localStorage.setItem('cartCount', count.toString());
  };

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Add to cart</button>
      <h3>Cart ({count})</h3>
    </div>
  );
};

// 在服务端获取状态数据,并将其传递给组件
StorageExample.getInitialProps = async ({ req }: NextPageContext) => {
  let initialCount = 0;
  if (req) {
    initialCount = Number(req.localStorage.getItem('cartCount'));
  } else {
    initialCount = Number(window.localStorage.getItem('cartCount'));
  }
  return { initialCount };
};

在上述代码中,我们通过 getInitialProps() 方法在服务端获取了 cartCount 的状态数据,并将其作为组件的初始化值传递给客户端。在客户端中,我们使用 localStorage 将状态数据持久化存储,以便在用户下次访问页面时恢复之前的状态。

总结

Next.js SSR 页面关闭后的状态维护是一个相对复杂的问题。本文介绍了两种解决方案。第一种方案使用 js-cookie 实现客户端存储。第二种方案则实现了一个客户端和服务端共同配合的方案,可以更好地保障数据的安全和完整性,但也需要更多的代码和实现成本。希望本文能够对大家有所帮助。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659e757cadd4f0e0ff7667f0


纠错反馈