Reactstrap innerRef 未设置对元素的引用

Reactstrap innerRef not setting reference to element

我正在尝试使用 Reactstrap 8.5.1 innerRef 属性和 useRef() 来在模态打开时将输入集中在模态中。下面的代码显示了打开模态框的按钮,但单击时出现错误“无法读取 属性 'focus' of null”。它还将 inputRef 写入控制台,这表明 .current 为空。

我尝试了多种设置 innerRef 的方法,但似乎没有任何效果。如果有人能指出我所缺少的东西,我将不胜感激。

import React, { useState, useRef, useEffect } from 'react';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button, Input } from 'reactstrap';


export const ModalSave = (props) => {
    const [modalIsOpen, setModalIsOpen] = useState(false);
    const toggle = () => setModalIsOpen(!modalIsOpen);

    const inputRef = useRef(null);

    useEffect(() => {
        console.log(inputRef);
        if (modalIsOpen === true) {
            inputRef.current.focus();
        }
    }, [modalIsOpen]);

    return (
        <div>
            <Button
                onClick={() => { setModalIsOpen(true); }}
            >Save</Button>
            <Modal isOpen={modalIsOpen} toggle={toggle}>
                <ModalHeader toggle={toggle}>Save</ModalHeader>
                <ModalBody>
                    Name:
                    <Input
                        innerRef={inputRef.current}
                    />
                </ModalBody>
                <ModalFooter>
                    <Button>Save</Button>
                    <Button onClick={toggle}>Close</Button>
                </ModalFooter>
            </Modal>
        </div>
    );
}

问题是打开模式不会触发组件重新渲染,这是获取输入 ref 值所需的,因此,ref 将保持 null 除非调用某些状态来触发重新渲染。作为一种解决方法,您可以使用 setTimeout() 方法来强制执行,如下所示:

useEffect(() => {
  if (modalIsOpen) {
   setTimeout(() => inputRef.current.focus(), 0);
  }
}, [modalIsOpen]);

更好的解决方案是使用 onOpened 模式打开后调用的方法:

export default function App() {
  const inputRef = useRef(null);
  const [modalIsOpen, setModalIsOpen] = useState(false);

  const toggle = () => setModalIsOpen(!modalIsOpen);
  const handleOpen = () => inputRef.current.focus();

  return (
    <div className="App">
      <div>
        <Button onClick={() => setModalIsOpen(true)}>Save</Button>
        <Modal isOpen={modalIsOpen} toggle={toggle} onOpened={handleOpen}>
          <ModalHeader toggle={toggle}>Save</ModalHeader>
          <ModalBody>
            Name:
            <Input innerRef={inputRef} />
          </ModalBody>
          <ModalFooter>
            <Button>Save</Button>
            <Button onClick={toggle}>Close</Button>
          </ModalFooter>
        </Modal>
      </div>
    </div>
  );
}