Maison > Questions et réponses > le corps du texte
J'utilise React-hook-form pour créer des composants de formulaire génériques profondément imbriqués et référencés via le paradigme useFormContext afin de permettre une imbrication arbitrairement profonde des composants. J'ai utilisé Chakra-UI pour le style. Tout cela fonctionne bien. Cependant, je voudrais ajouter un numéro de téléphone international à certains formulaires.
Je ne me soucie pas vraiment de la bibliothèque que j'utilise tant qu'elle est performante dans un contexte NextJS et fonctionne avec RHF et Chakra, je suis donc ouvert aux suggestions dans une direction complètement différente de celle ci-dessous.
Je pense que je suis sur le point d'utiliser React-International-Phone.
Le problème que j'ai (j'ai eu des problèmes similaires mais légèrement différents avec d'autres bibliothèques) est que React-International-Phone fonctionne bien avec Chakra ou React-Hook-Form, mais pas les deux en même temps.
Dans le code source de Github, React-international-phone a un exemple Storybook intégré à Chakra-UI qui fonctionne comme ceci :
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> ); };
Si j'utilise simplement le composant Chakra Input
dans les formes de crochet de réaction, cela ressemblerait à ceci :
<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>
Les deux problèmes qui combinent ces deux choses sont ...register
返回 ref
到 html 输入,而 React-international-phone 需要将 onChange
作为属性传递给其 usePhoneInput
les crochets.
Pour la première question, je pense que je peux utiliser cette réponse et exécuter
<Input value={phoneInput.phone} onChange={phoneInput.handlePhoneValueChange} name={name} ref={(el) => {reactHookRef(el); phoneInput.inputRef(el)}} />
Mais se plaindre phoneInput.inputRef
是一个对象而不是函数。事实上,文档说它是一个 React.RefObject<HTMLInputElement>
,这......我猜不是一个函数。但后来我不确定为什么 ref={phoneInput.inputRef}
fonctionne dans l'exemple de code.
Je pense que je peux résoudre le deuxième problème en refactorisant le formulaire de réaction-hook-form register
响应并将返回的onChange
传递给usePhoneInput
hook.
Au départ, j'ai essayé ça
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}} />
Mais le problème est que usePhoneInput
est un crochet, donc on ne peut pas réellement l'appeler ici. Ma position actuelle est
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}} />
Je me sensassez proche mais ça ne marche toujours pas. Je l'ai mis dans CodeSandbox. CodeSandbox est cassé, dans App.js j'ai commenté l'appel au formulaire car si je le décommente, cela bloque mon navigateur :(
Des idées sur la façon de connecter React-Hook-Form et Chakra-UI avec ceci ou toute autre bibliothèque de numéros de téléphone ?P粉6804879672024-03-28 00:17:15
Le conseil de @adsy dans les commentaires a résolu le problème.
Utiliser useController
dans un composant :
const PhoneNumberInput = ({ control, name, size='md' }) => { const { field, fieldState: { invalid, isTouched, isDirty }, formState: { touchedFields, dirtyFields } } = useController({ name, control }) const phoneInput = usePhoneInput({ defaultCountry: 'gb', onChange: (data) => { field.onChange(data.phone); } }) return ( <>> ) }; export default PhoneNumberInput; field.ref(el) && phoneInput.inputRef} /> phoneInput.setCountry(country.iso2)} renderButtonWrapper={({ children, rootProps }) => } />
(et modifications mineures de ref
dans les composants).
Puis quand vous l'appelez pour une imbrication profonde, déstructurez également control
:
{({ control, formState: { errors }, register}) => (