如何将一个React元素滚动到视图中

81 阅读2分钟

一个用例

偶尔我们建立的页面要提醒用户一些东西,但这些东西可能在他们的视野之外。一个例子是一个带有垂直滚动条的长表单,在表单提交后,有一个字段错误在视野之外。

在CodeSandbox中试试这个例子。把*"bad "*放在字段1中,滚动到最后一个字段,然后点击保存字段1包含一个错误,但你可能无法看到它,直到你向后滚动。

在这种情况下,我们要自动将问题字段滚动到用户视图中,以改善用户体验。

scrollIntoView

有一个方法叫做 scrollIntoView的方法存在于HTML元素上,我们可以使用它,它在所有现代浏览器上都被支持。这个方法将滚动元素的父容器,使其对用户可见。

很好!

在React中使用scrollIntoView

我们如何在React中使用scrollIntoView ?在React的世界里,我们通常不会强制性地调用DOM元素的方法

好吧,我们首先要获得我们想要调用scrollIntoView 的元素的引用。这些元素是我们例子中每个字段的div 容器:

const Field = ({ ... }: FieldProps) => {
  const fieldRef = React.useRef<HTMLInputElement>(null);  return (
    <div className="field" ref={fieldRef}>      ...
    </div>
  );
};

我们使用 useRef钩子把对div 的引用放到一个叫做fieldRef 的变量中。

然后我们可以使用 useEffect钩子来调用这个方法,当这个字段出现错误时:

const Field = ({ ... }: FieldProps) => {
  const fieldRef = React.useRef<HTMLInputElement>(null);
  React.useEffect(() => {    if (error && fieldRef.current) {      fieldRef.current.scrollIntoView();    }  }, [error]);  return ...
};

我们把error 道具放在useEffect 依赖数组中,这样每次错误发生时都会调用效果函数。在效果函数里面,我们使用fieldRef.current 访问字段div 元素,并在有错误时调用scrollIntoView ,并且我们有对div 的引用。

这就是了!当点击保存按钮时,问题字段会自动滚动到。

平稳过渡

我们可以做一个小的改进,使滚动更顺畅。 scrollIntoView钩子接收了一个scrollIntoViewOptions 对象参数。在该对象中,有一个behavior 属性,我们可以将其设置为"smooth"

fieldRef.current.scrollIntoView({
  behavior: "smooth",
});

注意,在写这篇文章的时候,scrollIntoViewOptions 在IE和Safari上是不可用的。所以,我们在这些浏览器上不会看到这个小改进。

这就完成了这个将React元素滚动到视图中的例子。最后一个例子是在CodeSandbox中,网址是codesandbox.io/s/scrollnto…