无法使用 react-hook-form 将表单元素集中在模式打开上
Unable to focus form element on modal open with react-hook-form
我正在尝试解决一个看起来很简单的问题。我想在模式打开后立即聚焦表单元素。
由于 react-hook-form
不提供表单引用的直接句柄,我正在尝试使用 useEffect
挂钩和 react-hook-form
s howngrown setFocus
函数但是我一直看到错误:
s.focus is not a function
代码
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
import {
ChakraProvider,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
Button,
ModalCloseButton,
useDisclosure
} from "@chakra-ui/react";
export default function App() {
const { setFocus, register } = useForm();
const { isOpen, onClose, onOpen } = useDisclosure();
useEffect(() => {
if (!isOpen) return;
setFocus("name");
}, [setFocus, isOpen]);
return (
<ChakraProvider>
<div className="App">
<Button onClick={onOpen}>Open</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<input {...register("name")} />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
</ChakraProvider>
);
}
阅读 Chakra 文档有一个 prop initialFocusRef
,您可以将 ref 传递给您最初要关注的元素
Chakra provides 2 props for this use case:
initialFocusRef: The ref of the component that receives focus when the modal opens.
finalFocusRef: The ref of the component that receives focus when the modal closes.
import { useEffect, useRef } from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
import {
ChakraProvider,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
Button,
ModalCloseButton,
useDisclosure
} from "@chakra-ui/react";
export default function App() {
const { setFocus, register } = useForm();
const { isOpen, onClose, onOpen } = useDisclosure();
const initialRef = useRef();
useEffect(() => {
//setFocus("name");
}, [setFocus, isOpen]);
return (
<ChakraProvider>
<div className="App">
<Button onClick={onOpen}>Open</Button>
<Modal isOpen={isOpen} onClose={onClose} initialFocusRef={initialRef}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<input {...register("name")} ref={initialRef} />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
</ChakraProvider>
);
}
根据评论更新
默认情况下,Chkra 焦点启用元素,如果您只需将 tabIndex
添加到您的元素并适当地赋予顺序值,那么它就会得到焦点。以前关闭按钮默认是聚焦的,现在在下面的代码中你会注意到我已经给关闭按钮 tabIndex=2 和给输入元素 tabIndex=1 并且它按预期工作。
<ChakraProvider>
<div className="App">
<Button onClick={onOpen}>Open</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton tabIndex="2" />
<ModalBody>
<input tabIndex="1" {...register("name")} />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
</ChakraProvider>
如果你想通过 ref 使用它,那么你可以检查“How to share ref usage?”,也许它会对你有所帮助。
也许 setFocus 不能 运行 因为首先卸载模态内容(和里面的输入)。
使用 setFocus 的一个简单解决方案是将表单作为一个独立的组件:
const Form = () => {
const { setFocus, register } = useForm();
useEffect(() => {
setFocus("name");
}, [setFocus]);
return <input {...register("name")} />;
};
然后将其包含在 modalBody 中。
我正在尝试解决一个看起来很简单的问题。我想在模式打开后立即聚焦表单元素。
由于 react-hook-form
不提供表单引用的直接句柄,我正在尝试使用 useEffect
挂钩和 react-hook-form
s howngrown setFocus
函数但是我一直看到错误:
s.focus is not a function
代码
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
import {
ChakraProvider,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
Button,
ModalCloseButton,
useDisclosure
} from "@chakra-ui/react";
export default function App() {
const { setFocus, register } = useForm();
const { isOpen, onClose, onOpen } = useDisclosure();
useEffect(() => {
if (!isOpen) return;
setFocus("name");
}, [setFocus, isOpen]);
return (
<ChakraProvider>
<div className="App">
<Button onClick={onOpen}>Open</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<input {...register("name")} />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
</ChakraProvider>
);
}
阅读 Chakra 文档有一个 prop initialFocusRef
,您可以将 ref 传递给您最初要关注的元素
Chakra provides 2 props for this use case:
initialFocusRef: The ref of the component that receives focus when the modal opens.
finalFocusRef: The ref of the component that receives focus when the modal closes.
import { useEffect, useRef } from "react";
import { useForm } from "react-hook-form";
import "./styles.css";
import {
ChakraProvider,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
Button,
ModalCloseButton,
useDisclosure
} from "@chakra-ui/react";
export default function App() {
const { setFocus, register } = useForm();
const { isOpen, onClose, onOpen } = useDisclosure();
const initialRef = useRef();
useEffect(() => {
//setFocus("name");
}, [setFocus, isOpen]);
return (
<ChakraProvider>
<div className="App">
<Button onClick={onOpen}>Open</Button>
<Modal isOpen={isOpen} onClose={onClose} initialFocusRef={initialRef}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<input {...register("name")} ref={initialRef} />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
</ChakraProvider>
);
}
根据评论更新
默认情况下,Chkra 焦点启用元素,如果您只需将 tabIndex
添加到您的元素并适当地赋予顺序值,那么它就会得到焦点。以前关闭按钮默认是聚焦的,现在在下面的代码中你会注意到我已经给关闭按钮 tabIndex=2 和给输入元素 tabIndex=1 并且它按预期工作。
<ChakraProvider>
<div className="App">
<Button onClick={onOpen}>Open</Button>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton tabIndex="2" />
<ModalBody>
<input tabIndex="1" {...register("name")} />
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
</ChakraProvider>
如果你想通过 ref 使用它,那么你可以检查“How to share ref usage?”,也许它会对你有所帮助。
也许 setFocus 不能 运行 因为首先卸载模态内容(和里面的输入)。
使用 setFocus 的一个简单解决方案是将表单作为一个独立的组件:
const Form = () => {
const { setFocus, register } = useForm();
useEffect(() => {
setFocus("name");
}, [setFocus]);
return <input {...register("name")} />;
};
然后将其包含在 modalBody 中。