在水化完成之前如何处理SSR文本框中的文本输入变化?

tom*_*tom 8 reactjs material-ui server-side-rendering

我正在研究一个简单的服务器端渲染(SSR)场景:只是一个登录页面,其中包含用户名和密码的文本输入。

与 SSR 一样,当客户端首次加载页面时,他们会获得服务器渲染的版本,该版本未经过水化。看起来不错,并且可以单击文本框并输入内容。

希望 JS 能够快速加载,并且在用户在框中输入任何内容之前就发生水合作用,并且一切正常。

但是,如果用户的网络速度很慢并且 JS 需要几秒钟才能加载怎么办?然后会发生以下情况:

  1. 用户在框中输入一些字符
  2. JS 突然加载,React 控制了输入框,并清除了它,因为初始状态是一个空字符串(!)
  3. 用户感到困惑,必须重新输入。

一定有一个最佳实践,对吗?我尝试过一些事情,例如测试 iftypeof window === "undefined"并将输入设置为disabledif so,但没有什么是令人满意的。我认为最好的用户体验是让水合组件拾取已键入的字符,但我也可以禁用编辑,直到水合完成。

FWIW 我正在使用 Material UI,它会带来一些额外的样式问题,但除此之外,我认为这个问题适用于任何 SSR 文本输入场景。

die*_*edu 5

根据这个问题,您可以做的是获取 dom 元素的 ref 并在安装组件时同步值

import React, { useState, useRef, useEffect } from "react";

export const Component = () => {
  const [value, setValue] = useState("");
  const inputRef = useRef(null);

  const onChange = (e) => {
    setValue(e.target.value);
  };

  useEffect(() => {
    const domValue = inputRef.current?.value;
    if (domValue) setValue(domValue);
  }, []);

  return <input ref={inputRef} type="text" value={value} onChange={onChange} />;
};
Run Code Online (Sandbox Code Playgroud)