Gohmz
Gohmz

Reputation: 1286

Integrate React-Semantic-UI and redux-form

I'm using redux-form (awesome libs) to handle my form & redux store in React app. Everything works well, important forms and nested json output.

I'm trying to use React-Semantic-UI Component with redux-form. I searched inside the docs how about integrate custom component with redux form, and here we go : http://redux-form.com/6.5.0/docs/faq/CustomComponent.md/ Seems perfect.

But when i integrate Semantic and this, it doenst work.

This is my simple test with pseudo code :

const TestComponent = props => (
<Form>
     <Field name="dropdownTest" component={ TestSelect } />
</Form>
)

and here my CustomComponent using Dropdown. You can found the dropdown documentation & props (onChange & value ) here :

http://react.semantic-ui.com/modules/dropdown

import Form , Dropdown from 'semantic-ui-react'
import {myOption from './myOption'

const TestSelect = field = (
   <Form.Field>
            <label> Test dropdown </label>
             <Dropdown option={myOption} selection 
                                   value={{val : field.input.value}}
                                   onChange={ param => field.input.onChange(param.val)} />
     </Form.Field>
)

As in the documentation, I added value & onChange props on my Custom Component.

I clearly miss something here. Is someone have simple example with redux-form and semantc ui ?

Thanks for helping.

Upvotes: 14

Views: 7958

Answers (2)

Chris
Chris

Reputation: 8422

I found the accepted answer wasn't working in my case, redux form kept firing a FOCUS action which kept triggering a re-render and my dropdown field would not open. Possibly my bad, or an update, but didn't have time to debug so came up with this solution.

I'm using Typescript, and wrapped the Semantic UI Dropdown field in a custom component that adds and retrieves the dropdown value from redux form directly.

Works well thus far, should be easy to port to vanilla JS.

ReduxFormSemanticDropdownComponent

If using Typescript change AppState to be your own state object type.

import { DropdownProps, Dropdown, Form, DropdownItemProps } from "semantic-ui-react";
import * as React from "react";
import { Dispatch } from "redux";
import { AppState } from "../../..";
import { change, formValueSelector } from "redux-form";
import { connect } from "react-redux";

interface OwnProps {
    name: string;
    form: string;
    label: string;
    placeholder?: string;
    options: Array<DropdownItemProps>;
}

interface DispatchProps {
    change: (form: string, field: string, value: string) => void;
}

interface StateProps {
    selectedValue: any;
}

type Props = OwnProps & DispatchProps & StateProps;

class ReduxFormSemanticDropdownComponent extends React.Component<Props> {

    onChange = (value: string) => {
        this.props.change(this.props.form, this.props.name, value);
    }

    render() {
        return (
            <Form.Field>
                <label>{this.props.label}</label>
                <Dropdown
                    placeholder={this.props.placeholder}
                    fluid
                    selection
                    value={this.props.selectedValue}
                    onChange={(event: React.SyntheticEvent<HTMLElement>, data: DropdownProps) => this.onChange(data.value as string)}
                    options={this.props.options}
                />
            </Form.Field>
        )
    }
}

const mapDispatchToProps = (dispatch: Dispatch<AppState>): DispatchProps => {
    return {
        change: (form: string, field: string, value: string) => dispatch(change(form, field, value)),
    };
};

const mapStateToProps = (state: AppState, ownProps: OwnProps): StateProps => {
    var selector = formValueSelector(ownProps.form);

    return {
        selectedValue: selector(state, ownProps.name)
    }
}

export const ReduxFormSemanticDropdown = connect<StateProps, DispatchProps, OwnProps>(mapStateToProps, mapDispatchToProps)(ReduxFormSemanticDropdownComponent);

To Use

Add this to your normal redux form, and it should behave as a standard field would.

<ReduxFormSemanticDropdown
    name="gigType"
    form="applicationForm"
    label="Gig Type"
    options={[
        {
            text: `I'm flexible!`,
            value: 'Flexible',
        },
        {
            text: 'Mid Week (Evening)',
            value: 'MidWeekEvening',
        },
        {
            text: 'Weekend (Afternoon)',
            value: 'WeekendAfternoon',
        },
        {
            text: 'Weekend (Evening)',
            value: 'WeekendEvening',
        }
    ]}
/>

Upvotes: 0

Gohmz
Gohmz

Reputation: 1286

Ok I succed :

To use React Semantic Dropdown, this is a simple example :

const TestComponent = props => (
<Form>
     <Field name="dropdownName" component={ DropdownFormField}
            label="Dropdown Test" 
      />

</Form>
)



const DropdownFormField = props => (
 <Form.Field>
   <Dropdown selection {...props.input}
             value={props.input.value}
             onChange={(param,data) => props.input.onChange(data.value)}
             placeholder={props.label} 
    />
  </Form.Field>
)

And everything is working great. You can do same with Semantic and any components.

Hope that somebody found this usefull.

Upvotes: 37

Related Questions