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>
);
}
我正在尝试使用 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>
);
}