Saya menggunakan react-hook-form untuk membina komponen bentuk generik yang sangat bersarang dan dirujuk melalui paradigma useFormContext untuk membolehkan sarang komponen dalam sewenang-wenangnya. Saya menggunakan Chakra-UI untuk penggayaan. Ini semua berfungsi dengan baik. Walau bagaimanapun, saya ingin menambah input nombor telefon antarabangsa pada beberapa borang.
Saya sebenarnya tidak kisah perpustakaan mana yang saya gunakan asalkan ia berprestasi dalam konteks NextJS dan berfungsi dengan RHF dan Chakra, jadi saya terbuka kepada cadangan dalam arah yang berbeza daripada di bawah.
Saya rasa saya sangat hampir menggunakan react-international-phone.
Masalah yang saya hadapi (saya mengalami masalah yang sama tetapi berbeza sedikit dengan perpustakaan lain) ialah telefon react-international berfungsi dengan baik sama ada dengan Chakra atau react-hook-form, tetapi bukan kedua-duanya pada masa yang sama .
Dalam kod sumber Github, react-international-phone mempunyai contoh Buku Cerita yang disepadukan dengan Chakra-UI yang berfungsi seperti ini:
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> ); };
Jika saya hanya menggunakan komponen Chakra Input
dalam bentuk react-hook-bentuk ia akan kelihatan seperti ini:
<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>
Dua isu yang menggabungkan dua perkara ini ialah ...register
返回 ref
到 html 輸入,而 React-international-phone 需要將 onChange
作為屬性傳遞給其 usePhoneInput
cangkuk.
Untuk soalan pertama saya rasa saya boleh gunakan jawapan ini dan laksanakan
<Input value={phoneInput.phone} onChange={phoneInput.handlePhoneValueChange} name={name} ref={(el) => {reactHookRef(el); phoneInput.inputRef(el)}} />
Tetapi mengeluh phoneInput.inputRef
是一個對象而不是函數(shù)。事實上,文檔說它是一個 React.RefObject<HTMLInputElement>
,這......我猜不是一個函數(shù)。但后來我不確定為什么 ref={phoneInput.inputRef}
berfungsi dalam kod contoh.
Saya rasa saya boleh menyelesaikan masalah kedua dengan memfaktorkan semula bentuk cangkuk tindak balas register
響應(yīng)并將返回的onChange
傳遞給usePhoneInput
cangkuk.
Mulanya saya mencuba ini
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}} />
Tetapi masalahnya ialah usePhoneInput
adalah cangkuk, jadi ia sebenarnya tidak boleh dipanggil di sana. Lokasi semasa saya ialah
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}} />
Saya rasa cukup dekat tetapi masih tidak berkesan. Saya telah memasukkannya ke dalam CodeSandbox. CodeSandbox rosak, dalam App.js saya mengulas panggilan ke borang kerana jika saya menyahkomennya ia akan mengunci penyemak imbas saya :(
Sebarang idea tentang cara menyambungkan react-hook-form dan chakra-ui dengan ini atau mana-mana perpustakaan nombor telefon lain?
Petua @adsy dalam komen menyelesaikan masalah.
Gunakan useController
dalam komponen:
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 }) => } />
(dan perubahan kecil kepada ref
dalam komponen).
Kemudian apabila anda memanggilnya untuk bersarang dalam, juga pemusnahan control
:
{({ control, formState: { errors }, register}) => (