如何使用React Hooks将某些内容集中在下一个渲染上

Kri*_*ekk 14 reactjs react-hooks

我正在玩钩子,我正在尝试做以下事情:

import React, { useState, useRef } from 'react';

const EditableField = () => {
  const [isEditing, setEditing] = useState(false);
  const inputRef = useRef();
  const toggleEditing = () => {
    setEditing(!isEditing);
    if (isEditing) {
      inputRef.current.focus();
    }
  };
  return (
    <>
      {isExpanded && <input ref={inputRef} />}
      <button onClick={toggleEditing}>Edit</button>
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

这将失败,因为它current是null,因为组件尚未重新渲染,并且输入字段尚未渲染(因此尚未聚焦).

这样做的正确方法是什么?我可以使用usePreviousReact Hooks FAQ中提出的钩子,但这似乎是一个痛苦的解决方法.

有不同的方式吗?

Tho*_*lle 29

更改useEffect后,每次渲染后都可以使用钩子运行函数isEditing.在这个功能可以检查是否isEditingtrue和重点投入.

const { useState, useRef, useEffect } = React;

const EditableField = () => {
  const [isEditing, setEditing] = useState(false);
  const toggleEditing = () => {
    setEditing(!isEditing);
  };

  const inputRef = useRef(null);

  useEffect(() => {
    if (isEditing) {
      inputRef.current.focus();
    }
  }, [isEditing]);
  
  return (
    <div>
      {isEditing && <input ref={inputRef} />}
      <button onClick={toggleEditing}>Edit</button>
    </div>
  );
};

ReactDOM.render(<EditableField />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/react@16.7.0-alpha.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.2/umd/react-dom.production.min.js"></script>
  
<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

  • 使用 Typescript,如果出现错误“Object is possible is 'null'.”,则必须输入引用“const inputRef = useRef&lt;HTMLInputElement&gt;(null);”并使用条件“if (inputRef.current)”。 (5认同)
  • `useLayoutEffect` 通常是 DOM 相关的突变和检查的首选。 (2认同)

Aru*_*ran 8

我知道接受的答案涵盖了上述问题中所要求的要素。

但作为补充说明,如果您使用函数式组件,请使用 来React.forwardRef传递对子组件的引用。对于稍后提到这个问题的人来说绝对有用。

以更简洁的方式,您可以编写接受ref以下给出的子组件:

    const InputField = React.forwardRef((props, ref) => {
        return (
            <div className={props.wrapperClassName}>
                <input 
                   type={props.type}
                   placeholder={props.placeholder} 
                   className={props.className}
                   name={props.name}
                   id={props.id}
                   ref={ref}/>
            </div>
        )
    })
Run Code Online (Sandbox Code Playgroud)