我使用ChakraUI来实现一个包含2个数字输入的弹出窗口。我的问题是,我不能把注意力集中在第二个数字输入上,它总是回到第一个数字上。我试过在useEffect中使用refs和设置焦点,但这并没有解决任何问题。下面可以找到一个足够的代码摘录:
在此相互依存:https://codesandbox.io/s/chakra-ui-react-hook-form-forked-w8dqy6?file=/src/index.js
function ListNewItem() {
return (
<div style={{ margin: 0 }}>
<Popover
returnFocusOnClose={false}
isOpen={show_new_listing}
onClose={() => setShowNewListing(false)}
placement='bottom'
closeOnBlur={false}
>
<PopoverTrigger>
<Box as='button' onClick={() => setShowNewListing(true)}>
<Text>List New Item</Text>
</Box>
</PopoverTrigger>
<PopoverContent backgroundColor={"black"} >
<div className="font-face-sfpb" color="white">
<PopoverHeader>Enter Listing Details</PopoverHeader>
</div>
<PopoverArrow />
<PopoverCloseButton/>
<PopoverBody>
<FocusLock returnFocus persistentFocus={false}>
<div className="font-face-sfpb">
<VStack align="center">
<HStack width="80%" align={"left"} >
<Box width="50%"><Text>Item:</Text></Box>
<Box width="50%">
<Text>Test Item</Text>
</Box>
</HStack>
<HStack width="80%" align={"left"} >
<Box width="50%"><Text>Price:</Text></Box>
<Box width="50%">
<NumberInput
id="desired_price"
ref={priceRef}
onChange={(valueString) => {setListPrice(checkParseInt(valueString)); console.log(valueString); console.log(priceRef.current)}}
value={list_price}>
<NumberInputField
autoFocus={false}
/>
</NumberInput>
</Box>
</HStack>
<HStack width="80%" align={"left"} >
<Box width="50%"><Text>Quantity:</Text></Box>
<Box width="50%">
<NumberInput
id="desired_quantity"
ref={quantityRef}
onChange={(valueString) => {setListQuantity(checkParseInt(valueString)); console.log(quantityRef.current)}}
value={list_quantity >= 0 ? list_quantity.toString() : ""}
>
<NumberInputField
autoFocus={false}
/>
</NumberInput>
</Box>
</HStack>
<Box as='button' onClick={ListItemOnMarketplace}>
<Text>LIST</Text>
</Box>
</VStack>
</div>
</FocusLock>
</PopoverBody>
</PopoverContent>
</Popover>
</div>
)
}
priceRef和quantityRef定义如下:
const priceRef = useRef<HTMLInputElement>(null);
const quantityRef = useRef<HTMLInputElement>(null);
如果你还需要什么,请告诉我。我已经尝试使用的效果,如:
useEffect(() =>
{
quantityRef.current?.focus();
}, [list_quantity]);
但是我不能让焦点停留在我当前使用的输入上。
非常感谢您的帮助
看起来您试图将焦点保持在第二个NumberInputField上,但是所提供的代码在呈现时没有将焦点设置在第二个输入上。相反,你可以使用NumberInput组件的onBlur事件在第二个输入失去焦点时将焦点返回给第二个输入。
这是你的代码的修改版本,应该保持关注第二个NumberInputField:
function ListNewItem() {
// ...
const handleQuantityInputBlur = () => {
setTimeout(() => {
quantityRef.current?.focus();
}, 0);
};
return (
// ...
<HStack width="80%" align={"left"} >
<Box width="50%"><Text>Quantity:</Text></Box>
<Box width="50%">
<NumberInput
id="desired_quantity"
ref={quantityRef}
onBlur={handleQuantityInputBlur}
onChange={(valueString) => {setListQuantity(checkParseInt(valueString)); console.log(quantityRef.current)}}
value={list_quantity >= 0 ? list_quantity.toString() : ""}
>
<NumberInputField autoFocus={false} />
</NumberInput>
</Box>
</HStack>
// ...
);
}
这段代码向NumberInput组件添加了一个onBlur事件,该组件调用handleQuantityInputBlur函数。该函数设置一个延迟为0ms的超时,确保在当前事件循环结束后焦点返回到第二个输入。
当你与第二个NumberInputField交互时,它应该保持焦点在第二个NumberInputField。