如何根据 Redux Form 中的另一个输入有条件地显示一个输入?

Posted

技术标签:

【中文标题】如何根据 Redux Form 中的另一个输入有条件地显示一个输入?【英文标题】:How to conditionally show an input based on another input in Redux Form? 【发布时间】:2016-10-02 03:53:40 【问题描述】:

当下拉值为others 时需要一个新的文本字段,但必须更改变量,因为building_typeothers 值放入新的文本字段中。在这种情况下,在哪里以及如何使两个变量相等?

import React from 'react'
import  connect  from 'react-redux'
import  reduxForm  from 'redux-form'
import  StandardForm, TextField, UsStatesSelectField, SelectField  from './../forms'
import  loadProperty, saveProperty  from './../../models/properties'

const validate = values => 
    const required = value => value ? null : 'Required'
    const errors = 
    errors.name = required(values.name)
    errors.street_address = required(values.street_address)
    errors.city = required(values.city)
    errors.state = required(values.state)
    errors.zip = required(values.zip)
    errors.building_type = required(values.building_type)

    return errors


const PropertyInfoForm = reduxForm(
    form: 'propertyInfo',
    fields: ['name', 'street_address', 'city', 'state', 'zip', 'building_type', 'building_other_type'],
    validate
)(React.createClass(
    render() 
        return (
            <StandardForm ...this.props title="Property Info" resetButton="Reset">
                <TextField ...this.props.fields.name label="Property Name" />
                <TextField ...this.props.fields.street_address label="Property    Address" />
                <div className="three fields">
                    <TextField ...this.props.fields.city label="City" />
                    <UsStatesSelectField ...this.props.fields.state label="State" />
                    <TextField ...this.props.fields.zip label="Zip Code" />
                </div>
                <SelectField ...this.props.fields.building_type
                    label="Please select a Building Type for the junctionbox"
                    options=[
                        ['office', 'Office'],
                        ['private_home', 'Private Home'],
                        ['residential', 'Residential'],
                        ['retail', 'Retail'],
                        ['restaurant', 'Restaurant'],
                        ['school', 'School'],
                        ['townhouse', 'Townhouse'],
                        ['warehouse', 'Warehouse'],
                        ['other', 'Other']
                    ]
                />
                ((this.props.fields.building_type.value) === 'other') ? (
                    <TextField ...this.props.fields.building_other_type label="Please Specify Other Building Type" />
                ) : ''
            </StandardForm>
        )
    
))

export default connect(
    (state, ownProps) => (
        property: state.entities.property[ownProps.params.propertyId]
    ),
    dispatch => (
        dispatch
    )
)(( dispatch, property ) => (
    <PropertyInfoForm
        initialValues=property
        onSubmit=(values) => dispatch(saveProperty(property.id, values)).then(_ => dispatch(loadProperty(property.id)))
    />
))

【问题讨论】:

SelectField 是您的自定义组件吗?如果是这样,select managed 的​​值在哪里? 假设SelectField 正在使用onChangevalue 做它应该做的事情,你的代码看起来不错。你试过只显示this.props.fields.building_type.value吗? 顺便说一句,你的问题的名字很糟糕。应该是,“” 我建议创建一个单独的字段组件 SelectOtherField 例如。该字段将管理值是来自选择还是文本输入。 【参考方案1】:

您可以使用formValueSelector

它可用于从connects mapStateToProps 函数内部的状态访问表单字段值,以便将该值作为道具传递给表单组件。

将表单字段值作为道具允许任何类型的值相关的事情。

1。 (小)条件Field示例

// SomeForm.jsx:

import React from 'react';
import connect from 'react-redux';
import Field, reduxForm, formValueSelector from 'redux-form';

let SomeComponentUseFirstFieldValue = (firstFieldValue, ...props) => 
    // do something with 'firstFieldValue'
    return (...);


const mapStateToPropsForSomeComponentUseFirstFieldValue = (state, initalProps) => 
    // Use 'initalProps.firstFieldValue' to retrieve something from state if needed.

    return ...;


const mapDispatchToPropsForSomeComponentUseFirstFieldValue = (dispatch, ownProps) => 
    // Use 'ownProps.firstFieldValue' to retrieve with dispatch


SomeComponentUseFirstFieldValue = connect(
    mapStateToPropsForSomeComponentUseFirstFieldValue, 
    mapDispatchToPropsForSomeComponentUseFirstFieldValue
)(SomeComponentUseFirstFieldValue);

let SomeForm = (handleSubmit, firstFieldValue, ...props) => (
    <form onSubmit=handleSubmit>
        <Field 
            name='first'
            component='input'
            type='text'
        />
        <Field
            name='second'
            component=SomeComponentUseFirstFieldValue
            firstFieldValue=firstFieldValue // Pass 'firstFieldValue' to Field component.
        />
        firstFieldValue && 
            <Field 
                ... // Conditional show Field.
            />
         
    </form>
);

SomeForm = reduxForm(
    // options
)(SomeForm);

const mapStateToPropsForSomeForm = (state, initialProps) => (
    firstFieldValue: (formValueSelector(initialProps.name))(state, 'first')
);

SomeForm = connect(
    mapStateToPropsForSomeForm
)(SomeForm);

export default SomeForm;

// 另一个组件.jsx:

import React from 'react';
import SomeForm from 'SomeForm';

const AnotherComponent = (props) => (
    <SomeForm
        name='form1'
        initialValues=...
        ...
    />
)

2。解决您的问题

import React from 'react';
import connect from 'react-redux';
import reduxForm from 'redux-form';
import StandardForm, TextField, UsStatesSelectField, SelectField from './../forms';
import loadProperty, saveProperty from './../../models/properties'

const validate = values => 
    const required = value => value ? null : 'Required'
    const errors = 
    errors.name = required(values.name)
    errors.street_address = required(values.street_address)
    errors.city = required(values.city)
    errors.state = required(values.state)
    errors.zip = required(values.zip)
    errors.building_type = required(values.building_type)

    return errors


let PropertyInfoForm = (props) => (
    <StandardForm ...props title="Property Info" resetButton="Reset">
        <TextField ...props.fields.name label="Property Name" />
        <TextField ...props.fields.street_address label="Property    Address" />
        <div className="three fields">
            <TextField ...props.fields.city label="City" />
            <UsStatesSelectField ...props.fields.state label="State" />
            <TextField ...props.fields.zip label="Zip Code" />
        </div>
        <SelectField ...props.fields.building_type
            label="Please select a Building Type for the junctionbox"
            options=[
                ['office', 'Office'],
                ['private_home', 'Private Home'],
                ['residential', 'Residential'],
                ['retail', 'Retail'],
                ['restaurant', 'Restaurant'],
                ['school', 'School'],
                ['townhouse', 'Townhouse'],
                ['warehouse', 'Warehouse'],
                ['other', 'Other']
            ]
        />
        (props.buildingTypeValue === 'other') ? (
            <TextField ...props.fields.building_other_type label="Please Specify Other Building Type" />
        ) : ''
    </StandardForm>
)

PropertyInfoForm = reduxForm(
    form: 'propertyInfo',
    validate: validate,
    fields: [
        'name', 
        'street_address', 
        'city', 'state', 
        'zip', 
        'building_type', 
        'building_other_type'
        ],
)(PropertyInfoForm);

const mapStateToProps = (state, initialProps) => (
    property: state.entities.property[initialProps.params.propertyId],
    buildingTypeValue: (formValueSelector(initialProps.name))(state, 'building_type')
);

const mapDispatchToProps = dispatch => (
    dispatch // Mhh... Passing 'dispatch' directly to props smells bad...
);

PropertyInfoForm = (dispatch, property, buildingTypeValue) => (
    <PropertyInfoForm
        initialValues=property
        onSubmit=
            values => dispatch(
                saveProperty(property.id, values)).then(_ => dispatch(loadProperty(property.id))
            )
        
        buildingTypeValue=buildingTypeValue
    />
);

PropertyInfoForm = connect(
    mapStateToProps,
    mapDispatchToProps
)(PropertyInfoForm);

export default PropertyInfoForm;

【讨论】:

以上是关于如何根据 Redux Form 中的另一个输入有条件地显示一个输入?的主要内容,如果未能解决你的问题,请参考以下文章

如何清除表单中的某些字段 - Redux-Form

如何避免或禁用 Redux 表单文本输入中的自动完成功能?

如何使用AngularJS中的另一个输入更改密码验证?

如何根据 Access 2013 中的另一个输入字段更新表单上的字段?

如何使用 redux-form 在不同组件(向上一个组件)中显示 FieldArray 中的字段

在 React、Redux-Form 和 GraphQL 中选择输入中的 onChange 事件从数据库中查询