【问题标题】:Reactstrap innerRef not setting reference to elementReactstrap innerRef 未设置对元素的引用
【发布时间】:2021-02-24 10:03:54
【问题描述】:

我正在尝试使用 Reactstrap 8.5.1 innerRef 属性和 useRef() 来在模态打开时将输入集中在模态中。下面的代码显示了打开模态的按钮,但是单击时出现错误“无法读取 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>
    );
}

【问题讨论】:

    标签: reactjs reactstrap


    【解决方案1】:

    问题是打开模式不会触发组件重新渲染,这是获取输入 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>
      );
    }
    

    【讨论】:

    • 感谢您的精彩回答!你是对的,更好的解决方案是使用 onOpened。我已经更改了我的代码来使用它,它现在可以工作了。
    猜你喜欢
    • 2016-01-25
    • 2020-04-19
    • 1970-01-01
    • 2020-08-24
    • 2012-12-29
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多