繁体   English   中英

如何将值从自定义组件类传递到redux-form?

[英]How to pass value from custom component class to redux-form?

我正在以redux形式调用自定义组件。

<Field name="myField" component={SiteProjectSelect}/>

此组件是两个组合框的组合。 第二个框取决于第一个框的值-即取决于您选择的站点,您可以从项目列表中进行选择。 我想做的就是获取表格以接收选定的站点和选定的项目。 但是,我不确定如何将值传递给redux-form。

class SiteProjectSelect extends Component {
    constructor() {
        super();
        this.state = {
            selectedSite: null,
            selectedProject: null,
        };
    }

    handleSiteSelection = selectedSite => {
        console.log(selectedSite)
        this.setState({ selectedSite, selectedProject: null });
    };

    handleProjectSelection = selectedProject => {
        this.setState({ selectedProject });
        this.props.input.onChange(selectedProject.value); 
    };

    render() {
        const selectedRow = this.state.selectedSite ? projects.find((node) => node.site === this.state.selectedSite.value) : "";
        const filteredProjectOptions =  selectedRow ? selectedRow.projects.map(project => ({ value: project, label: project })) : []

        return (
            <div {...this.props} >
                <label>Site</label>
                <div style={{ marginBottom: '20px' }} >
                    <Select
                        name="site"
                        value={this.state.selectedSite}
                        onChange={this.handleSiteSelection}
                        options={siteOptions}
                        isSearchable
                    />
                </div>
                <div style={{ marginBottom: '20px' }} >
                    <label>Project</label>
                    <Select
                        name="project"
                        value={this.state.selectedProject}
                        onChange={this.handleProjectSelection}
                        options={filteredProjectOptions}
                        isMulti
                        isSearchable
                        closeMenuOnSelect={false}
                    />
                </div>
            </div>
        );
    }
}

我终于确定了。 对于偶然发现此问题的其他人,这是我需要知道的。 要使用自定义组件,

  • 使用onChange属性设置字段的新值。 当您需要更改组件的值并将新值传递给它时,可以通过调用onChange函数this.props.input.onChange(your-components-new-value-here)来实现。
  • 现在,此新值将存储在value prop: this.props.input.value 因此,无论在组件的渲染功能中需要传递/显示组件当前值的任何地方,都应使用value属性。 它必须是value prop,而不是其他变量,例如您传递给onChange函数的变量。 这样做是为了控制显示与value道具绑定到的redux表单的状态。 为什么这有用? 例如,您可以在用户完成操作后将其带到表单查看页面,然后在用户想要进行更多更改时返回到表单。 redux-form如何知道如何重新填充所有显示的内容,而无需让用户再次填写表单? 因为显示取决于状态,而不是用户输入! 花了我一段时间才能理解所有这些内容!!

在我的示例中,当我使用两个react-select组件时,其中一个依赖于另一个组件,最终我不得不使用Fields组件,这使我可以在组件中拥有两个Field,而不仅仅是一个。 一旦实现了这一点,就很明显我不需要在组件中具有单独的状态,因为两个字段的value始终可以通过它们各自的value属性来访问。 所以,是的,我毕竟可以只使用无状态功能!

我用以下方式调用组件:

<Fields names={["site", "projects"]} component={SiteProjectSelect} />

我最后的工作组件:

class SiteProjectSelect extends Component {
    handleSiteSelection = selectedSite => {
        this.props.site.input.onChange(selectedSite);
        this.props.projects.input.onChange(null);
    };

    handleProjectSelection = selectedProjects => {
        this.props.projects.input.onChange(selectedProjects);
    };

    renderSite = () => {
        const {
            input: { value },
            meta: { error, touched }
        } = this.props.site;

        return (
            <div>
                <label>Site</label>
                <div style={{ marginBottom: '20px' }}>
                    <Select
                        name="site"
                        value={value}
                        onChange={this.handleSiteSelection}
                        options={siteOptions}
                        isSearchable
                    />
                </div>
                <div className="red-text" style={{ marginBottom: '20px' }}>
                    {touched && error}
                </div>
            </div>
        );
    };

    renderProjects = () => {
        var {
            input: { value },
            meta: { error, touched }
        } = this.props.projects;

        const selectedSite = this.props.site.input.value;

        const selectedRow = selectedSite
            ? projects.find(node => node.site === selectedSite.value)
            : '';
        const filteredProjectOptions = selectedRow
            ? selectedRow.projects.map(project => ({
                    value: project,
                    label: project
              }))
            : [];

        return (
            <div>
                <div style={{ marginBottom: '20px' }}>
                    <label>Projects</label>
                    <Select
                        name="projects"
                        value={value}
                        onChange={this.handleProjectSelection}
                        options={filteredProjectOptions}
                        isMulti
                        isSearchable
                        closeMenuOnSelect={false}
                    />
                </div>
                <div className="red-text" style={{ marginBottom: '20px' }}>
                    {touched && error}
                </div>
            </div>
        );
    };

    render() {
        return (
            <div>
                {this.renderSite()}
                {this.renderProjects()}
            </div>
        );
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM