整合 React-Semantic-UI 和 redux-form

Integrate React-Semantic-UI and redux-form

我正在使用 redux-form(很棒的库)来处理我的表单 & redux 存储在 React 中 应用程序。 一切正常,重要的形式和嵌套的 json 输出。

我正在尝试将 React-Semantic-UI 组件与 redux-form 一起使用。 我在文档中搜索了如何将自定义组件与 redux 表单集成,然后我们开始: http://redux-form.com/6.5.0/docs/faq/CustomComponent.md/ 看起来很完美。

但是当我将 Semantic 与此集成时,它确实有效。

这是我用伪代码进行的简单测试:

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

这里是我的 CustomComponent 使用 Dropdown。您可以在此处找到下拉文档和道具(onChange 和值):

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>
)

如文档中所述,我在我的自定义组件上添加了 value 和 onChange 道具。

我显然在这里漏掉了什么。有人有 redux-form 和 semantc ui 的简单示例吗?

感谢您的帮助。

好的,我成功了:

要使用 React Semantic Dropdown,这是一个简单的例子:

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>
)

一切都很好。 您可以对语义和任何组件执行相同的操作。

希望有人觉得这很有用。

我发现已接受的答案在我的情况下不起作用,redux 表单不断触发 FOCUS 操作,该操作不断触发 re-render 并且我的下拉字段无法打开。可能是我的问题,或者更新了,但是没有时间调试所以想出了这个解决方案。

我正在使用 Typescript,并将语义 UI 下拉字段包装在一个自定义组件中,该组件直接从 redux 表单添加和检索下拉值。

目前运行良好,应该很容易移植到 vanilla JS。

ReduxFormSemanticDropdownComponent

如果使用 Typescript,请将 AppState 更改为您自己的状态对象类型。

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);

使用

将其添加到您的普通 redux 表单中,它的行为应该与标准字段一样。

<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',
        }
    ]}
/>