使用Redux在两个React表单组件之间进行通信

时间:2016-07-22 12:01:13

标签: reactjs redux react-redux

假设您有一个类似下面的表单来添加新人:

spec

在此示例中,当您从填充的选择列表中选择国家/地区时,将使用基于所选国家/地区的选项填充城市选择元素。此表单页面(CountrySelectionForm)由以下组件组成:

  • CountrySelectionForm
  • CitySelectionForm

这里的问题是:我应该如何将选择从CitySelectionForm组件传达给PersonCreationForm组件?我有几个选择,但我不确定在Redux世界中处理这个问题的方法是什么:

  • onCountrySelected组件内,只需连接CountrySelectionForm的{​​{1}}道具并将结果通过其CitySelectionForm道具传递给country。无需通过Redux进行此通信。但是,更改country道具会触发CitySelectionForm的更改,以根据Redux商店中选定的国家/地区获取城市。
  • 在国家/地区选择中,PersonCreationForm组件会调度指示选择了哪个国家/地区的操作。在此基础上,PersonCreationForm会收到通知,并通过CitySelectionForm道具将结果传递给country。这会触发CitySelectionForm的更改,以便根据Redux商店中选定的国家/地区获取城市。
  • 在国家/地区选择中,PersonCreationForm组件会调度指示选择了哪个国家/地区的操作。基于此,CitySelectionForm会收到通知。这会触发CitySelectionForm的更改,以便根据Redux商店中选定的国家/地区获取城市。

4 个答案:

答案 0 :(得分:4)

我强烈建议您在这种情况下使用redux-form。在你的情况下,它将是这样的:

render() {
  const {fields, handleSubmit} = this.props
  return (   
    <form>
      <CountrySelectInput {...fields.country}/>
      <CitySelectInput {...field.city} country={fields.country.value}/>
      <input type="text" {...fields.name}/>
      <button type="submit" onClick={handleSubmit(this.addHandler)}>Add</button>
    </form>
  )
}

要完成这项工作,您应该在ContrySelectInput和CitySelectInput组件中处理“value”和“onChange”道具。像普通输入一样。

Redux-form模块将显着简化您使用表单的生活。您可以使用干净的redux(列表中的选项1)执行类似的操作。它仍然是正确的。

答案 1 :(得分:1)

有一种可能的方式来确定您可以使用哪个选项:

如果您不需要在整个应用中共享数据,并且组件具有相同的父级,,您可以使用本地状态执行此操作。因此,它节省了您的时间,因为您不需要编写动作,缩减器代码等,并且您不需要任何抽象。

如果您需要在整个应用中共享数据然后,您可以使用redux内容

答案 2 :(得分:0)

我必须使用react-reduxredux-form做类似的事情。你可以这样做:

AddUserForm.js:

render() {
    const {fields, handleSubmit} = this.props
    return (
        <form onSubmit={handleSubmit}>
            <CountrySelect {...fields.country} />
            <CitySelect {...fields.city} />
        </form>
    )
}

CountrySelect.js:

import { updateCities } from 'actions'
...
render() {
    const {handleChange, ...rest} = this.props
    return (
        <select {...rest} onChange={handleChange}>
            <option value="USA">USA</option>
            ...
        </select>
    )
}

const mapDispatchToProps = (dispatch) => {
    return {
        handleChange: (event) => {
            let countryId = event.target.value
            dispatch(updateCities(countryId))
            return countryId
        }
    }
}

export default connect(null, mapDispatchToProps)(CountrySelect)

CitySelect.js:

render() {
    const {cities, ...rest} = this.props
    return (
        <select {...rest}>
            {cities.map(city => {
                return (
                    <option key={city} value={city}>{city}</option>
                )
            })}
        </select>
    )
}

const mapStateToProps = (state) => {
    return {
        cities: state.cities
    }
}

export default connect(mapStateToProps)(CitySelect)

actions.js:

函数updateCities会将redux state.cities设置为如下所示的数组:

state.cities = [
    'Los Angeles',
    'New York',
    ...
]

答案 3 :(得分:0)

此用例不需要Redux。您可以将CountrySelectionForm组件用作具有内部状态的包装器。

两个选择CitySelectionFormsetState()必须通过道具接收一个专用处理程序,当'onSelect'事件中的子组件内部触发它们时执行CitySelectionForm

由于智能组件CountrySelectionForm管理的状态,PersonCreationForm组件将通过道具收到val myList = #['Hello', 'World'] val String[] myArray = #['Hello', 'World'] 的值。