如何使用 React Hooks 专注于下一次渲染

IT技术 reactjs react-hooks
2021-04-21 01:59:04

我在玩钩子,我正在尝试执行以下操作:

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>
    </>
  );
};

这将失败,因为它current是 null,因为组件还没有重新渲染,输入字段还没有渲染(因此还不能聚焦)。

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

有不同的方法吗?

3个回答

您可以使用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"));
<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>

useLayoutEffect 通常首选用于与 DOM 相关的突变和检查。
2021-06-05 01:59:04
使用 Typescript,如果出现错误Object is possibly 'null'.,则必须输入 refconst inputRef = useRef<HTMLInputElement>(null);并使用条件if (inputRef.current)
2021-06-22 01:59:04

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

但作为附加说明,如果您正在使用功能组件,请利用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>
        )
    })
这如何回答问题?
2021-05-27 01:59:04

或者简单地使用这个组件

import { FC, useEffect, useRef } from 'react'

export const FocusedInput: FC<JSX.IntrinsicElements['input']> = (props) => {

    const inputRef = useRef<null | HTMLElement>(null)
    useEffect(() => {
        inputRef.current!.focus()
    }, [])
    return <input {...props} type="text" ref={inputRef as any} />
}

为什么inputRef as any如果没有这个演员,它不应该正确输入吗?
2021-05-26 01:59:04