【发布时间】:2022-01-21 02:17:59
【问题描述】:
我在 React 中构建了一个自动完成输入,使用 Chakra UI 进行样式设置。我还使用 react-hook-form 来处理表单提交钩子。
当我使用自动完成填写表格时,我可以成功地从下拉列表中选择一个选项。但是,在提交表单时,React-Hook-Form 似乎认为我没有填写这些字段,因为没有提交任何内容并且没有调用 onSubmit 调用。
我使用 forwardRef 将 ref 传递给输入,这应该是注册这些字段所需要的全部内容。
这是一个沙箱,可以让调试更容易 - 请注意,提交时没有调用日志,RHF 也没有任何错误 - 应该出现两者之一 - https://codesandbox.io/s/chakra-hook-fail-49ppb
表格代码为:
const test: AutoCompleteSuggestions[] = [
{key: "US", value: "USA"},
{key: "UK", value: "United Kingdom"},
]
function onSubmit(values: QueryFormParams) {
console.log('V'); //Never gets called
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<FormControl isInvalid={errors.name}>
<AutoComplete
{...register('selectedDeparture', {
required: 'Select a departure',
})}
placeholder={'Departure country...'}
isValid={v => setIsItemSelected(v)}
suggestions={test}
/>
</FormControl>
</form>
)
自动补全代码如下:
import React, {Ref, useState} from 'react';
import {Input, Table, Tbody, Td, Tr, VStack} from '@chakra-ui/react';
type AutoCompleteProps = {
suggestions: AutoCompleteSuggestions[]
isValid: (b: boolean) => void
placeholder: string
}
export type AutoCompleteSuggestions = {
key: string,
value: string
}
// eslint-disable-next-line react/display-name
export const AutoComplete = React.forwardRef(({suggestions, isValid, placeholder}: AutoCompleteProps, ref: Ref<HTMLInputElement>) => {
const [filteredSuggestions, setFilteredSuggestions] = useState<AutoCompleteSuggestions[]>();
const [showSuggestions, setShowSuggestions] = useState<boolean>(false);
const [userInput, setUserInput] = useState<string>('');
function onChange(e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) {
console.log('Changing', userInput, e.currentTarget.value);
const newUserInput = e.currentTarget.value;
if (!newUserInput) {
//setActiveSuggestion(-1);
setFilteredSuggestions([]);
setShowSuggestions(false);
isValid(true);
setUserInput(e.currentTarget.value);
}
const filteredSuggestions = suggestions.filter(suggestion => suggestion.value.toLowerCase().startsWith(userInput.toLowerCase()));
//setActiveSuggestion(e.target.innerText);
setFilteredSuggestions(filteredSuggestions);
setShowSuggestions(true);
isValid(false);
setUserInput(e.currentTarget.value);
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
function onClick(e: MouseEvent<HTMLLIElement, MouseEvent>) {
console.log('Clicked', e.target.innerText);
setFilteredSuggestions([]);
setShowSuggestions(false);
isValid(true);
setUserInput(e.target.innerText);
}
let suggestionsListComponent;
if (showSuggestions && userInput) {
if (filteredSuggestions?.length) {
suggestionsListComponent = (
<Table className={'suggestions'} position={'absolute'} top={10} left={0} right={0} variant='simple' zIndex={999}>
<Tbody>
{filteredSuggestions?.map((suggestion, index) => {
return (
<Tr key={index}
_hover={{
background: 'gray.200',
color: 'green',
}}
onClick={onClick}>
<Td>
<span className={'selectedText'}>{suggestion.value}</span>
</Td>
</Tr>
);
})}
</Tbody>
</Table>
);
} else {
suggestionsListComponent = (
<div className="no-suggestions">
<em>No countries found for that input!</em>
</div>
);
}
}
return (
<>
<VStack position={'relative'}>
<Input
ref={ref}
type="text"
onChange={onChange}
value={userInput}
placeholder={placeholder}
/>
{suggestionsListComponent}
</VStack>
</>
);
});
export default AutoComplete;
【问题讨论】:
-
应该有codeandbox演示,因为它有很多代码,我还是不明白你的问题是什么:(
-
codesandbox.io/s/chakra-hook-fail-49ppb @TanNguyen 看到这个沙箱 - 提交时没有调用日志,也没有显示错误
-
把它放到你的帖子(在头),以便其他人可以看到^^
-
是我自己还是 CodeSandbox 不工作?
-
@whygee 请立即查看
标签: javascript reactjs react-hooks react-hook-form chakra-ui