React:将重点放在 componentDidMount 上,如何用钩子来做?

IT技术 javascript reactjs
2021-03-29 04:54:03

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

class Foo extends React.Component {
    txt1 = null;

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

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

我正在尝试使用新的hooks 提案重写此组件

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

2个回答

您可以使用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第一次调用时?
2021-05-23 04:54:03
@notgiorgi 给出的参数useRef是 ref 的current属性应该是什么值,所以初始值为{ current: null }. 提供一个空数组作为第二个参数,useEffect使其效果仅在初始渲染后运行一次,这正是 OP 想要的。
2021-06-07 04:54:03
啊,谢谢,我忘了初始渲染之后useEffect运行而不是之前
2021-06-15 04:54:03

根据官方文档: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 的一种方式。如果您将 ref 对象传递给 React with <div ref={myRef} />,React 会.current在该节点发生更改时将其属性设置为相应的 DOM 节点。

但是,useRef()有用的不止是ref属性。保持任何可变值类似于您在类中使用实例字段的方式,这很方便。

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

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