yaserso
yaserso

Reputation: 2868

How to add react-phone-number-input to -react-final-form?

I'm currently creating a form using react-final-form and trying to use react-phone-number-input with it through integration as an adapter, as displayed through this example.

I attempted to use the example to learn how it is done, but I'm not sure how to access the component and create the adapter for it properly.

import React from 'react';
import { Form, Field } from 'react-final-form';
import PhoneInput from 'react-phone-number-input';

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const onSubmit = async values => {
  await sleep(300)
  window.alert(JSON.stringify(values, 0, 2))
}

const PhoneAdapter = ({ input, meta, ...rest }) => (
    <PhoneInput
    {...input}
    {...rest}
    value={input.value}
    onChange={(event, value) => input.onChange(value)}
  />
  )

class ContactForm extends React.Component {
    render() {
        return (
            <>
            <Form
              onSubmit={onSubmit}
              initialValues={{ }}
              render={({ handleSubmit, form, submitting, pristine, values }) => (
                <form onSubmit={handleSubmit}>
                  <fieldset>
                  <Field component={PhoneAdapter} />
                  </fieldset>
                  <fieldset>
                    <button type="submit" disabled={submitting || pristine}>
                      Submit
                    </button>
                  </fieldset>
                  <pre>{JSON.stringify(values, 0, 2)}</pre>
                </form>
              )}
            />
            </>
        );
    }
}

export default ContactForm;

Upvotes: 3

Views: 3849

Answers (1)

yaserso
yaserso

Reputation: 2868

Update: July 2019

Apparently, all you need to do is to spread the input property of Field. Works flawlessly. Learn about spreading if you're not familiar with it.

const PhoneAdapter = ({ input }) => (
    <PhoneInput {...input} />
)

<Field name="phone" placeholder="Enter phone number" component={PhoneAdapter} />

I ended up experimenting with the FieldRenderProps props until it worked out. I wasn't so sure whether it would work or not, as react-phone-number-input is two elements in a component. I thought it would implement the input on only one of the elements.

By using input, I gain access to the input's props. Hence, I called upon it's value, as the default looks like so:

<PhoneInput
  placeholder="Enter phone number"
  value={ this.state.value } // This is what I called.
  onChange={ value => this.setState({ value }) }/>

I then did the same for the onChange function prop.

const PhoneAdapter = ({ input }) => (
    <PhoneInput value={input.value.value} onChange={value => input.onChange(value)} />
)

Finally, I used the component adapter like so:

<Field name="phone" placeholder="Enter phone number" component={PhoneAdapter} />

Upvotes: 3

Related Questions