Search code examples
reactjssemantic-ui-reactreact-final-form

React-Final-Form with DropDown in Child Component, how?


I'm trying to use React-final-form with a DropDown in a Child Component. Can't get this to work.

All of my text fields are already in a Child Component and this works like a charm. The field in the parent looks like this:

<Field
    name="lastName"
    placeholder="Last Name"
    validate={required}
>
    {({input, meta, placeholder}) => (
        <MyField meta={meta} input={input} placeholder={placeholder}/>
    )}
</Field>

The Child Component looks like this:

export const MyField = (props) => {
    return (
        <Form.Field className={props.meta.active ? 'active' : ''}>
            <Label>{props.label ? props.label : props.placeholder}</Label>
            <Form.Input
                {...props.input}
                placeholder={props.placeholder}
                className={(props.meta.error && props.meta.touched ? 'error' : '')}
            />
        </Form.Field>
    )
};

The "Form.Field" and "Label" are coming from semantic-ui-react

But now I want to do the same with a DropDown. The standard DropDown, taken from an example on the React-Final-Form site, looks like this:

<Field name="toppingsA" component="select">
    <option value="chicken">Chicken</option>
    <option value="ham">Ham</option>
    <option value="mushrooms">Mushrooms</option>
    <option value="cheese">Cheese</option>
    <option value="tuna">Tuna</option>
    <option value="pineapple">Pineapple</option>
</Field>

And it works in a sense that I'm getting the value in my react-final-form values onSubmit. then I'm trying to offload the Dropdown itself to the Child Component (with the intention to use the semantic-ui-react version of a Dropdown, but first things first and get the Dropdown to work :-) )

Parent Component:

const eatOptions = [
    {key: 'c', text: 'Chicken', value: 'chicken'},
    {key: 'h', text: 'Ham', value: 'ham'},
    {key: 'm', text: 'Mushrooms', value: 'mushrooms'},
    {key: 't', text: 'Tuna', value: 'tuna'}
];

// And in the Form:
<Field name="toppingsB" component="select" options={eatOptions}>
    { ({input,  meta, options}) => {
        return (
            <Opts options={options} name={input.name}/>
        )
    }}
</Field>

And in the Child Component:

export const Opts = (props) => {
    return (
        <select name={props.name}>
            {props.options.map((x) => {
                return (
                    <option key={x.key} value={x.value}>{x.text}</option>
                )
            })}
        </select>
    )
};

Result is that the HTML looks the same (which does not say that much I guess), ToppingsA is picked up in the values (on onSubmit) and ToppingsB is not. I can't figure out what am I missing here and your help would be very much appreciated.

Thanks in advance, Bert


Solution

  • @S.Taylor, Thanks for your help!! It works.

    As a reference the working code:

    The Field in Parent Component:

    <Field name="toppingsB" options={eatOptions} >
        { ({input,  meta, options}) => {
            return (
                <Opts
                    options={options}
                    name={input.name}
                    onChange={ (value) => input.onChange(value)}
                />
            )
        }}
    </Field>
    

    And the code in the Child Component:

    export const Opts = (props) => {
        return (
            <select name={props.name} onChange={props.onChange}>
                {props.options.map((x) => {
                    return (
                        <option key={x.key} value={x.value}>{x.text}</option>
                    )
                })}
            </select>
        )
    };