如何在渲染后用React设置元素的焦点(附代码)

1,103 阅读3分钟

简介

通过设置一个元素的焦点,我们轻轻地引导用户到下一个预期的输入区域,给他们一个更好的浏览体验,减少猜测。

在这篇文章中,我们将学习如何在渲染我们的React应用程序或React组件后将焦点设置在一个元素上。

在传统的HTML中,使用我们的<input> 标签中的autofocus 属性来设置一个元素的焦点是很容易的,这个属性是一个布尔属性,默认设置为false 。它指示浏览器将焦点放在那个特定的输入字段上,用户可以立即开始输入值:

<form>
    <input type="text" autofocus> // Will focus
    <input type="text"> // Won't focus
</form>

这在我们的React应用程序中也会起作用。尽管如此,当我们想在渲染后以更多的程序控制来设置元素的焦点时--我们可以利用功能组件中的useEffect() 钩子和类组件中的componentDidMount() 生命周期方法。

如何在功能组件中在渲染后设置元素的焦点

以前,在引入React钩子之前,我们无法用Functional组件处理这样的操作。

自从引入钩子后,我们可以知道我们的应用程序/组件何时完全渲染,这样我们就可以使用useEffect() 钩子执行特定的操作。我们还可以访问useRef() 钩子,我们可以用它来直接引用一个特定的元素。

假设我们有一个有两个字段的表单,我们希望其中一个字段在组件渲染后被设置为焦点:

const App = () => {
    return (
        <div className='container'>
            <form>
                <input type="text" placeholder='This has focus' />
                <input type="text" placeholder='No focus when we render' />
            </form>
        </div>
    )
}
export default App;

让我们开始使用useRef() React钩子获得对输入的引用。要做到这一点,我们首先要从React导入useRef() ,创建一个ref ,并将其默认值设为null,然后通过ref 属性将创建的ref 附加到我们的React元素上:

import { useRef } from 'react';

const App = () => {
    const inputReference = useRef(null);

    return (
        <div className='container'>
            <form>
                <input type="text" ref={inputReference} placeholder='This has focus' />
                <input type="text" placeholder='No focus when we render' />
            </form>
        </div>
    )
}
export default App;

:注意我们只将创建的引用附加到其中一个输入元素上,也就是我们想设置为焦点的那个。

现在让我们继续使用useEffect() 钩子,在渲染我们的应用程序后将焦点添加到该元素:

import { useRef, useEffect } from 'react'

const App = () => {
    const inputReference = useRef(null);

    useEffect(() => {
        // ...
    }, [])

    return (
        <div className='container'>
            <form>
                <input type="text" ref={inputReference} placeholder='This has focus' />
                <input type="text" placeholder='No focus when we render' />
            </form>
        </div>
    )
}
export default App;

在上面的代码中,注意到我们导入了useEffect() 钩子,然后用一个空的依赖数组([])来使用这个钩子,以确保它只在组件最初安装时启动。最后,为了使被引用的元素成为焦点,我们将通过current 属性访问ref,然后附加focus() 方法:

useEffect(() => {
    inputReference.current.focus();
}, [])

在这一点上,当我们的应用程序或组件渲染时,被引用的元素将自动被聚焦:

import { useRef, useEffect } from 'react';

const App = () => {
    const inputReference = useRef(null);

    useEffect(() => {
        inputReference.current.focus();
    }, []);

    return (
        <div className='container'>
            <form>
                <input type="text" ref={inputReference} placeholder='This has focus' />
                <input type="text" placeholder='No focus when we render' />
            </form>
        </div>
    )
}
export default App;

如何在类组件的渲染后设置元素的焦点

到目前为止,我们已经看到了如何在功能组件中设置元素的焦点,但在类组件中,这是一个完全不同的语法,因为我们不再使用钩子,因为它们只在功能组件中工作。在类组件中,我们在constructor() 方法中创建我们的ref,并利用componentDidMount() 方法,在我们的应用程序渲染时将被引用的元素设置为焦点:

import React, { Component } from 'react';

export class App extends Component {
    constructor(props) {
        super(props);
        this.inputReference = React.createRef();
    }

    componentDidMount() {
        this.inputReference.current.focus();
    }

    render() {
        return (
            <div className='container'>
                <form>
                    <input type="text" ref={this.inputReference} placeholder='This has focus' />
                    <input type="text" placeholder='No focus when we render' />
                </form>
            </div>
        )
    }
}
export default App;

在上面的代码中,我们使用constructor() 方法来创建一个引用,并将其连接到输入元素:

constructor(props) {
    super(props);
    this.inputReference = React.createRef();
}

然后我们使用componentDidMount() 生命周期方法,这与useEffect() 钩子非常相似,以确保一旦我们的应用程序/组件渲染,该元素被设置为焦点:

componentDidMount() {
    this.inputReference.current.focus();
}

结论

在这篇文章中,我们已经学会了如何在我们的应用程序或组件在类和功能组件中渲染后,使用输入字段将一个元素设置为焦点。这两种方法都是一样的,但由于它们是两种不同类型的组件,所以有不同的语法。