Reputation: 1286
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
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
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