【问题标题】:React: set focus on componentDidMount, how to do it with hooks?React:将焦点放在componentDidMount上,如何用钩子做?
【发布时间】:2018-11-07 11:22:27
【问题描述】:

在 React 中,通过类,我可以在组件加载时将焦点设置为输入,如下所示:

class Foo extends React.Component {
    txt1 = null;

    componentDidMount() {
        this.txt1.focus();
    }

    render() {
        return (
            <input type="text"
                ref={e => this.txt1 = e}/>
        );
    }
}

我正在尝试使用新的hooks proposal 重写此组件。

我想我应该使用useEffect 而不是componentDidMount,但是我该如何重写焦点逻辑呢?

【问题讨论】:

  • 只是想提一下,也可以在不需要 JS 的情况下在输入本身上设置自动对焦属性,例如:&lt;input type="text" autofocus="true" /&gt;。我知道这不是您问题的直接答案,这就是为什么我把它放在评论中并且我不想使给定的答案无效,我会这样做。我只是认为在很多情况下,直接设置属性并完成它就足够了。

标签: javascript reactjs


【解决方案1】:

您可以使用useRef 钩子创建一个引用,然后将其集中在useEffect 钩子中,并以一个空数组作为第二个参数,以确保它仅在初始渲染后运行。

const { useRef, useEffect } = React;

function Foo() {
  const txt1 = useRef(null);

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

  return <input type="text" ref={txt1} />;
}

ReactDOM.render(<Foo />, document.getElementById("root"));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.production.min.js"></script>

<div id="root"></div>

【讨论】:

  • 第一次调用时为什么不是txt1 null
  • @notgiorgi 给useRef 的参数是ref 的current 属性应该是什么值,所以初始值为{ current: null }。将一个空数组作为第二个参数提供给 useEffect 使得效果仅在初始渲染后运行一次,这正是 OP 想要的。
  • 啊,谢谢,我忘记了 useEffect 在初始渲染之后而不是之前运行
【解决方案2】:

根据官方文档:https://reactjs.org/docs/hooks-reference.html#useref 你可以使用useRef

useRef 返回一个可变 ref 对象,其 .current 属性初始化为传递的参数 (initialValue)。返回的对象将在组件的整个生命周期内持续存在。

一个常见的用例是命令式地访问一个孩子:

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

本质上,useRef 就像一个“盒子”,可以在其 .current 属性中保存可变值。

您可能熟悉 refs 主要是作为访问 DOM 的一种方式。如果您使用 &lt;div ref={myRef} /&gt; 将 ref 对象传递给 React,那么只要该节点发生更改,React 就会将其 .current 属性设置为相应的 DOM 节点。

不过,useRef() 的用处远不止ref 属性。它可以方便地保留任何可变值,类似于在类中使用实例字段的方式。

这是因为 useRef() 创建了一个纯 JavaScript 对象。 useRef() 和自己创建 {current: ...} 对象之间的唯一区别是 useRef 将在每次渲染时为您提供相同的 ref 对象。

请记住,useRef 不会在其内容更改时通知您。改变 .current 属性不会导致重新渲染。如果你想在 React 将 ref 附加或分离到 DOM 节点时运行一些代码,你可能需要使用回调 ref 来代替。

【讨论】:

    猜你喜欢
    • 2019-08-24
    • 2021-01-10
    • 2017-05-15
    • 2011-09-28
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    相关资源
    最近更新 更多