Ich möchte meine drei Ansätze zum Umgang mit kaskadierenden Formularfeldern teilen.
Erster Ansatz, Verwendung von Zustandsvariablen
Hier in diesem Beitrag sehen wir den zweiten Ansatz, bei dem gewöhnliche Variablen verwendet werden, um kaskadierende Formularfelder basierend auf Länder-, Bundesland- und Stadtdaten zu verarbeiten.
react-native-element-dropdown react-native-paper
Wir verwenden React-Native-Element-Dropdown für Dropdown-Felder
import React, { useState, useEffect } from "react"; import { View, Text, StyleSheet, TouchableOpacity } from "react-native"; import { Dropdown } from "react-native-element-dropdown"; export default function App() { return ( <View> <p>ZDropDown is a custom component. </p> <h3> Sample data </h3> <pre class="brush:php;toolbar:false">const listCountry = [ { countryId: "1", name: "india" }, { countryId: "2", name: "uk" }, { countryId: "3", name: "canada" }, { countryId: "4", name: "us" }, ]; const listSate = [ { stateId: "1", countryId: "1", name: "state1_india" }, { stateId: "4", countryId: "2", name: "state1_uk" }, { stateId: "7", countryId: "3", name: "state1_canada" }, { stateId: "10", countryId: "4", name: "state1_us" }, ]; const listCity = [ { cityId: "1", stateId: "1", countryId: "1", name: "city1_state1_country1", }, { cityId: "6", stateId: "2", countryId: "1", name: "city6_state2_country1", }, { cityId: "7", stateId: "3", countryId: "1", name: "city7_state3_country1", }, { cityId: "23", stateId: "8", countryId: "3", name: "city23_state8_country3", }, { cityId: "30", stateId: "10", countryId: "4", name: "city30_state10_country4", }, { cityId: "35", stateId: "12", countryId: "4", name: "city35_state12_country4", }, { cityId: "36", stateId: "12", countryId: "4", name: "city36_state12_country4", }, ];
Im ersten Ansatz haben wir 4 Zustandsvariablen verwendet, aber hier verwenden wir 4 gewöhnliche Variablen (3 für Dropdown, 1 für Fokusfeld) und eine Zustandsvariable, die zum Umschalten und Auslösen des Zustandseffekts (Seite aktualisieren) verwendet wird.
var country = { list: [], selectedCountry: {}, selectedValue: null, }; var state = { list: [], selectedState: {}, selectedValue: null, }; var city = { list: [], selectedCity: {}, selectedValue: null, }; var focusField = ''; export default function App() { const [refreshPage, setRefreshPage] = useState(false); return ( <View> <p>Focus and Blur events get triggered more than onChange event so it is better to maintain a separate variable to represent the focus field and avoid data mess up situations. </p> <h3> Load Country </h3> <p>Load country dropdown from the sample data. (you can use api call)<br> </p> <pre class="brush:php;toolbar:false">export default function App() { . . . const loadCountry = () => { // load data from api call country.list = [...listCountry]; // switching value will refresh the ui setRefreshPage(!refreshPage); }; useEffect(() => { loadCountry(); }, []); return ( . . . )
Wir verwenden eine Funktion, um das Fokusfeld festzulegen und die Seite durch Wechseln der Statusvariablen (refreshPage) zu aktualisieren
const changeFocusField = (fld = '') => { focusField = fld; setRefreshPage(!refreshPage); };
<Text>Country</Text> <ZDropDown . . . isFocus={focusField === 'country'} onFocus={() => changeFocusField('country')} onBlur={() => changeFocusField('')} onChange={null} /> <Text>State</Text> <ZDropDown . . . isFocus={focusField === 'state'} onFocus={() => changeFocusField('state')} onBlur={() => changeFocusField('')} onChange={null} /> <Text>City</Text> <ZDropDown . . . isFocus={focusField === 'city'} onFocus={() => changeFocusField('city')} onBlur={() => changeFocusField('')} onChange={null} />
Wir sind jetzt zur Hälfte fertig.
Beim ausgewählten Land müssen wir die entsprechenden Staaten STAATEN basierend auf der Länderauswahl laden.
Aktualisieren Sie das Länderfeld, konzentrieren Sie sich auf das Land und laden Sie STAATEN basierend auf dem Land.
<Text>Country</Text> <ZDropDown . . . onChange={(item) => { country.selectedCountry = item; country.selectedValue = item.countryId; focusField = ''; loadState(); }} />
Haben Sie den Unterschied beim ersten Ansatz gesehen? Zuvor wurden drei Statusvariablen aktualisiert, hier wird jedoch nur eine Statusvariable aktualisiert.
Wenn sich das Land ändert, werden sowohl Bundesstaaten als auch Städte geändert. Bevor wir den neuen Wert einrichten, müssen wir also die vorhandenen Daten löschen.
const loadState = async () => { state = { list: [], selectedState: {}, selectedValue: null }; city = { list: [], selectedCity: {}, selectedValue: null }; const arr = listSate.filter( (ele) => ele.countryId === country.selectedValue ); if (arr.length) { state.list = arr; } refreshPage(!refreshPage); };
Und laden Sie das Stadtfeld basierend auf Land und Bundesland.
<Text>State</Text> <ZDropDown . . . onChange={(item) => { state.selectedValue = item.stateId; state.selectedState = item; changeFocusField(''); loadCity(); }} />
const loadCity = async () => { city = { list: [], selectedCity: {}, selectedValue: null }; const arr = listCity.filter((ele) => ele.stateId === state.selectedValue); if (arr.length) city.list = arr; setRefreshPage(!refreshPage); };
Fertig, die Formularfelder funktionieren jetzt ordnungsgemäß.
Zwei weitere zusätzliche Funktionen, eine ist das Zurücksetzen der Seite und die andere ist das Anzeigen einer Warnung.
Formularvariablen und Fokusvariablen sollten gelöscht werden.
. . . const resetForm = () => { country = {list: [...listCountry],selectedCountry: {}, selectedValue: null}; state = { list: [], selectedState: {}, selectedValue: null }; city = { list: [], selectedCity: {}, selectedValue: null }; focusField = ''; setRefreshPage(!refreshPage); }; . . . <TouchableOpacity onPress={() => resetForm()}> <h3> Warning </h3> <p>We have to show a warning msg if the parent field value is null. For that we are using SnackBar component from paper.<br> </p> <pre class="brush:php;toolbar:false">import { Snackbar } from "react-native-paper"; . . . var snackMsg = ''; export default function App() { . . . const [visible, setVisible] = useState(false); const onToggleSnackBar = () => setVisible(!visible); const onDismissSnackBar = () => setVisible(false); . . . return ( <View> <p>We moved snackMsg to ordinary variable from state variable.</p> <p>Since State and City fields have parent field, they have to be validated.<br> </p> <pre class="brush:php;toolbar:false"> <Text>State</Text> <ZDropDown onFocus={() => { focusField('state'); if (!country.selectedValue) { snackMsg = 'Select country'; onToggleSnackBar(); changeFocusField('country'); } }} . . . /> <Text>City</Text> <ZDropDown onFocus={() => { focusField('city'); if (!country.selectedValue) { snackMsg = 'Select country'; onToggleSnackBar(); changeFocusField('country'); } else if (!state.selectedValue) { snackMsg = 'Select state'; onToggleSnackBar(); changeFocusField('state'); } }} . . . />
Fertig.
Vielen Dank.
Vollständige Codereferenz hier
Das obige ist der detaillierte Inhalt vonKaskadierende Form React Native verbessert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!