2016-07-22 7 views
8

Angenommen, Sie ein Formular wie unten hat eine neue Person hinzuzufügen:Kommunikation zwischen zwei Reagieren Formularkomponenten mit Redux

enter image description here

In diesem Beispiel, wenn Sie ein Land aus der bevölkerten Auswahlliste wählen, die Das city select-Element wird mit Optionen für das ausgewählte Land gefüllt. Diese Formularseite (PersonCreationForm) besteht aus folgenden Komponenten:

  • CountrySelectionForm
  • CitySelectionForm

Die Frage ist: Wie soll ich die Auswahl von CountrySelectionForm Komponente CitySelectionForm Komponente kommunizieren? Ich habe ein paar Optionen im Auge, aber ich bin nicht sicher, was der perefered Weg wäre dies in Redux Welt zu handhaben:

  • Innerhalb der PersonCreationForm Komponente nur durch die onCountrySelected Stütze des CountrySelectionForm Einhaken und vorbei das Ergebnis CitySelectionForm durch seine country prop. Es ist nicht nötig, Redux für diese Kommunikation zu verwenden. Wenn Sie jedoch die country Requisite ändern, wird eine Änderung in CitySelectionForm ausgelöst, um Städte basierend auf dem ausgewählten Land von Redux Store zu erhalten.
  • Bei der Länderauswahl löst die Komponente PersonCreationForm die Aktion aus, die angibt, welches Land ausgewählt ist. Basierend darauf wird PersonCreationForm benachrichtigt und übergibt das Ergebnis an CitySelectionForm durch ist country Prop. Das löst eine Änderung in CitySelectionForm aus, um Städte basierend auf dem ausgewählten Land von Redux Store zu erhalten.
  • Bei der Länderauswahl löst die Komponente PersonCreationForm die Aktion aus, die angibt, welches Land ausgewählt ist. Basierend darauf wird CitySelectionForm benachrichtigt. Das löst eine Änderung in CitySelectionForm aus, um Städte basierend auf dem ausgewählten Land von Redux Store zu erhalten.

Antwort

4

Ich würde Ihnen wärmstens empfehlen, redux-form für solche Situationen zu verwenden. In Ihrem Fall wäre es so etwas wie diese:

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

Um diese Arbeit zu machen, sollen Sie „Wert“ und „onChange“ Requisiten in Ihrem ContrySelectInput und CitySelectInput Komponenten verarbeiten. Wie bei normalen Eingaben.

Redux-Form-Modul wird Ihr Leben mit den Formen erheblich vereinfachen. Sie können so etwas mit einem sauberen Redux tun (Option 1 in Ihrer Liste). Und es wird immer noch stimmen.

+0

danke! eine Frage ohne Bezug: Was macht '{fields.country}' dort? ist es eine andere Möglichkeit, Requisiten zu übergeben? Ich nehme an, das ist ein Spread-Operator in ES6, oder? – tugberk

+0

Redux-Form-Container stellt der Komponente "fields" -Stütze zur Verfügung. Und "fields.country" ist eigentlich ein Objekt mit solchen Eigenschaften wie "Wert", "OnChange", "Fehler" und so weiter. Und '{... fields.country}' fügt einfach alle diese Eigenschaften der Komponente hinzu. –

+0

Ich sehe, so '' ist äquivalent zu ', richtig? – tugberk

1

eine möglich Art und Weise, welche Option Sie verwenden können, um zu bestimmen, ist:

Wenn Sie die Daten über die App zu teilen, NICHT brauchen und Komponenten haben die gleichen Eltern, dann Sie kann es mit lokalem Staat tun. Daher spart es Ihnen Zeit, weil Sie keine Aktionen, Reducer-Codes usw. schreiben müssen und keine Abstraktionen benötigen.

WENN Sie müssen die Daten über die App teilen, dann können Sie redux Sachen verwenden

0

ich etwas tun musste, ähnlich react-redux und redux-form verwenden. Man könnte so etwas tun:

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:

Der Spaß ction updateCities wird redux state.cities auf ein Array gesetzt, das wie folgt aussieht:

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

Sie brauchen Redux nicht für diesen Anwendungsfall. Sie können die Komponente PersonCreationForm als Wrapper mit einem internen Status verwenden.

Die beiden wählt CountrySelectionForm und CitySelectionForm haben von Requisiten einen dedizierten Handler zu erhalten, die eine setState() durchführen, wenn sie innerhalb Kinder Komponenten auf der ‚onSelect‘ Ereignis ausgelöst werden.

Die CitySelectionForm Komponente wird von Requisiten der Wert von CountrySelectionForm dank der von der Smart-Komponente PersonCreationForm verwaltet werden.