【问题标题】:Warning: Text content did not match. Server: "I'm out" Client: "I'm in" div警告:文本内容不匹配。服务器:“我出去了”客户端:“我进来了”div
【发布时间】:2021-05-28 03:27:15
【问题描述】:

我在 Next.js 项目中使用universal-cookie,这是在控制台中返回警告的简单代码:

import React, { useState } from "react";
import Cookies from "universal-cookie";
import styles from "../styles/Home.module.css";

export default function Home() {
  const cook = new Cookies();
  const [session, setSession] = useState(cook.get("key"));
  const setCookie = () => {
    cook.set("key", "hola", { secure: true });
    setSession(cook.get("key"));
  };
  const deleteCookie = () => {
    cook.remove("key", { secure: true });
    setSession(undefined);
  };

  return (
    <div className={styles.container}>
      <button onClick={() => setCookie()}>Save Cookie</button>
      <button onClick={() => deleteCookie()}>Delete Cookie</button>
      {session ? <>I'm in</> : <>I'm out</>}
    </div>
  );
}

当“I'M IN”然后我刷新页面时,控制台中会出现以下警告:

我已经到处寻找解决方案了。

【问题讨论】:

    标签: reactjs cookies next.js


    【解决方案1】:

    Next.js pre-renders every page 在服务器上。

    这意味着Next.js会提前为每个页面生成HTML, 而不是全部由客户端 JavaScript 完成。

    (...) 当一个 页面由浏览器加载,其 JavaScript 代码运行并生成 页面完全互动。 (这个过程称为水合作用。)

    浏览器上呈现的 HTML 与服务器上生成的不匹配,因为 cook.get("key") 在两者中返回的内容不同。

    有几个选项可以解决这个问题。


    #1 将设置状态移动到useEffect

    第一个解决方案是将状态设置移动到 useEffect 中。

    export default function Home() {
        const cook = new Cookies();
        const [session, setSession] = useState();
        
        // `setCookie` and `deleteCookie` code here
    
        useEffect(() => {
            setSession(cook.get("key"));
        }, []);
    
        return (
            <div className={styles.container}>
                <button onClick={() => setCookie()}>Save Cookie</button>
                <button onClick={() => deleteCookie()}>Delete Cookie</button>
                {session ? <>I'm in</> : <>I'm out</>}
            </div>
        );
    }
    

    #2 使用next/dynamic{ ssr: false }

    作为替代解决方案,也可以通过使用{ ssr: false } 动态导入带有next/dynamic 的React 组件来规避该问题,无论在何处使用该组件。这可以防止组件被包含在服务器上,并且只在客户端动态加载它。

    const Home = dynamic(
        () => import('../components/Home'),
        { ssr: false }
    )
    

    【讨论】:

      猜你喜欢
      • 2019-06-05
      • 2018-12-28
      • 1970-01-01
      • 2020-11-15
      • 2021-02-10
      • 1970-01-01
      相关资源
      最近更新 更多