NextJS SSR 和客户端状态

NextJS SSR and Client side state

我有以下 nextJS 应用程序:


export default function Home({ productsData }) {
  const [user, setUser] = useState(null);
  const [products, setProducts] = useState([]);

  useEffect(() => {
    if (productsData) setProducts(productsData);
  }, [productsData]);

  useEffect(() => {
    const userLocal = window.localStorage.getItem("user");
    if (userLocal) {
      setUser(JSON.parse(userLocal));
    }
  }, []);

  return (
    <div className="container">
      <ul className="row">
        {products.map((product) => {
          return (
            <h1>
              {product.translation.name} -{" "}
              {user
                ? user.premium
                  ? product.prices.premium
                  : product.prices.price
                : product.prices.price}
            </h1>
          );
        })}
      </ul>
    </div>
  );
}

export async function getServerSideProps() {
  const data = [
    {
      prices: {
        premium: 25,
        price: 59.95,
      },
      translation: {
        name: "Product 1",
      },
    },
    {
      prices: {
        premium: 25,
        price: 29.95,
      },
      translation: {
        name: "Product 2",
      },
    },
  ];
  return {
    props: {
      productsData: data,
    },
  };
}

这有效,但如果我向本地主机发出“curl”请求,我看不到服务器正在呈现任何内容,这是因为 useEffect 设置“产品”发生在客户端。

但是如果我这样做: const [products, setProducts] = useState(productsData);

然后我有这个错误: 错误:Hydration 失败,因为初始 UI 与服务器上呈现的内容不匹配。 - 公交车 Google

那么,我是否必须在 SSR 和在客户端拥有状态之间做出选择?

我试过了const [products, setProducts] = useState(productsData);

这次你不需要useEffect!

你可以为此使用加载

export default function Home({ productsData }) {
  const [user, setUser] = useState(null);
  

  useEffect(() => {
    const userLocal = window.localStorage.getItem("user");
    if (userLocal) {
      setUser(JSON.parse(userLocal));
    }
  }, []);

  return (
    <div className="container">
      <ul className="row">
        {productsData?.map((product) => {
          return (
            <h1>
              {product.translation.name} -{" "}
              {user
                ? user.premium
                  ? product.prices.premium
                  : product.prices.price
                : product.prices.price}
            </h1>
          );
        })}
      </ul>
    </div>
  );
}

export async function getServerSideProps() {
  const data = [
    {
      prices: {
        premium: 25,
        price: 59.95,
      },
      translation: {
        name: "Product 1",
      },
    },
    {
      prices: {
        premium: 25,
        price: 29.95,
      },
      translation: {
        name: "Product 2",
      },
    },
  ];
  return {
    props: {
      productsData: data,
    },
  };
}