Ich verwende „react-hook-form“, um generische Formularkomponenten zu erstellen, die tief verschachtelt sind und über das useFormContext-Paradigma referenziert werden, um eine beliebig tiefe Verschachtelung von Komponenten zu ermöglichen. Für das Styling habe ich Chakra-UI verwendet. Das alles funktioniert gut. Allerdings möchte ich einigen Formularen die Eingabe einer internationalen Telefonnummer hinzufügen.
Es ist mir eigentlich egal, welche Bibliothek ich verwende, solange sie in einem NextJS-Kontext performant ist und mit RHF und Chakra funktioniert, daher bin ich offen für Vorschläge in eine ganz andere Richtung als unten.
Ich glaube, ich bin kurz davor, „react-international-phone“ zu verwenden.
Das Problem, das ich habe (ich hatte ähnliche, aber leicht unterschiedliche Probleme mit anderen Bibliotheken), ist, dass React-International-Phone entweder mit Chakra oder React-Hook-Form gut funktioniert, aber nicht mit beiden gleichzeitig.
Im Github-Quellcode von React-International-Phone ist ein Storybook-Beispiel in die Chakra-UI integriert, das so funktioniert:
export const ChakraPhone = ({ value, onChange, }) => { const phoneInput = usePhoneInput({ defaultCountry: 'us', value, onChange: (data) => { onChange(data.phone); }, }); return ( <ChakraProvider> <Input value={phoneInput.phone} onChange={phoneInput.handlePhoneValueChange} ref={phoneInput.inputRef} /> </ChakraProvider> ); };
Wenn ich nur die Chakra-Komponente Input
in React-Hook-Formen verwende, würde es so aussehen:
<ConnectForm> {({ formState: { errors }, register}) => ( <form> <FormControl isInvalid={errors.phone}> <FormLabel htmlFor='phone'>Phone Number</FormLabel> <Input id='phone' name='phone' {...register('phone')} /> </FormControl> </form> )} </ConnectForm>
Die beiden Probleme, die diese beiden Dinge kombinieren, sind ...register
返回 ref
到 html 输入,而 React-international-phone 需要将 onChange
作为属性传递给其 usePhoneInput
Haken.
Für die erste Frage denke ich, dass ich diese Antwort verwenden und ausführen kann
<Input value={phoneInput.phone} onChange={phoneInput.handlePhoneValueChange} name={name} ref={(el) => {reactHookRef(el); phoneInput.inputRef(el)}} />
Aber sich beschweren phoneInput.inputRef
是一个对象而不是函数。事实上,文档说它是一个 React.RefObject<HTMLInputElement>
,这......我猜不是一个函数。但后来我不确定为什么 ref={phoneInput.inputRef}
funktioniert im Beispielcode.
Ich denke, ich kann das zweite Problem lösen, indem ich den React-Hook-Form-register
响应并将返回的onChange
传递给usePhoneInput
Hook umgestalte.
Zuerst habe ich das versucht
const PhoneNumberInput = (props) => { return ( <ConnectForm> {({ formState: { errors }, register }) => { const { onChange, onBlur, name, ref: reactHookRef } = register('phone'); const phoneInput = usePhoneInput({ defaultCountry: 'gb', onChange: onChange }) return ( <ConnectForm> <Input type='tel' value={phoneInput.phone} onChange={phoneInput.handlePhoneValueChange} name={name} ref={(el) => {reactHookRef(el); phoneInput.inputRef}} />
Aber das Problem ist, dass usePhoneInput
ein Hook ist und daher dort eigentlich nicht aufgerufen werden kann. Mein aktueller Standort ist
const PhoneNumberInput = (props) => { const [ onChangeRHF, setOnChangeRHF ] = useState(); const phoneInput = usePhoneInput({ defaultCountry: 'gb', onChange: onChangeRHF }) return ( <ConnectForm> {({ formState: { errors }, register }) => { const { onChange, onBlur, name, ref: reactHookRef } = register('phone'); setOnChangeRHF(onChange); return ( <> <InputGroup size={props?.size} id={props?.id || 'phone'}> <InputLeftAddon width='4rem'> <CountrySelector selectedCountry={phoneInput.country} onSelect={(country) => phoneInput.setCountry(country.iso2)} renderButtonWrapper={({ children, rootProps }) => <Button {...rootProps} variant={'outline'} px={'4px'} mr={'8px'}> {children} </Button> } /> </InputLeftAddon> <Input type='tel' value={phoneInput.phone} onChange={phoneInput.handlePhoneValueChange} onBlur={onBlur} name={name} ref={(el) => {reactHookRef(el); phoneInput.inputRef}} />
Ich fühlenah genug dran, aber es funktioniert immer noch nicht. Ich habe es in CodeSandbox eingefügt. CodeSandbox ist kaputt, in App.js habe ich den Aufruf des Formulars auskommentiert, denn wenn ich den Kommentar entferne, wird mein Browser blockiert :(
Irgendwelche Ideen, wie man React-Hook-Form und Chakra-UI mit dieser oder einer anderen Telefonnummernbibliothek verbinden kann?
评论中 @adsy 的提示解决了这个问题。
在组件中使用
useController
:(以及组件中
ref
的细微更改)。然后,当您调用它进行深度嵌套时,也解构
control
: