如何根据 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_type
将others
值放入新的文本字段中。在这种情况下,在哪里以及如何使两个变量相等?
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
正在使用onChange
和value
做它应该做的事情,你的代码看起来不错。你试过只显示this.props.fields.building_type.value
吗?
顺便说一句,你的问题的名字很糟糕。应该是,“”
我建议创建一个单独的字段组件 SelectOtherField
例如。该字段将管理值是来自选择还是文本输入。
【参考方案1】:
您可以使用formValueSelector
。
它可用于从connect
s 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 中的另一个输入有条件地显示一个输入?的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 Access 2013 中的另一个输入字段更新表单上的字段?