Hello! 欢迎来到小浪资源网!



React Native 的基本级联形式


我想分享我处理级联表单字段的 3 种方法。

  1. 第一种方法是通用的,使用状态变量。
  2. 第二种是使用普通变量和一个布尔状态变量来触发状态效果(刷新页面)。
  3. 第三种是带有普通变量的动态表单字段。

在这篇文章中,我们看到第一种方法,即基于国家、州、城市数据处理级联表单字段的常用方法。

套餐

react-native-element-dropdown react-native-paper 

我们正在使用react-native-element-dropdown作为下拉字段

基页

React Native 的基本级联形式

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 style={styles.container}>       <view>         <text>country</text>         <zdropdown           data={[]}           labelfield=""           valuefield=""           value={null}           isfocus={false}           onchange={null}         />         <text>state</text>                 <zdropdown           data={[]}           labelfield=""           valuefield=""           value={null}           isfocus={false}           onchange={null}               />         <text>city</text>         <zdropdown           data={[]}           labelfield=""           valuefield=""           value={null}           isfocus={false}           onchange={null}               />       </view>       <view>         <text>selected country</text>         <text style={styles.selectedvalue}>{country.selectedcountry.name}</text>         <text>selected state</text>         <text style={styles.selectedvalue}>{state.selectedstate.name}</text>         <text>selected city</text>         <text style={styles.selectedvalue}>{city.selectedcity.name}</text>       </view>       <touchableopacity onpress={null} style={styles.clrbtn}>         <text style={styles.clrbtntxt}>reset</text>       </touchableopacity>     </view>   ); }  const zdropdown = ({   data,   labelfield,   valuefield,   value,   onfocus,   onblur,   onchange,   isfocus, }) => {   return (     <dropdown       mode={"auto"}       style={[styles.dropdown, isfocus ? { bordercolor: "dodgerblue" } : {}]}       placeholderstyle={styles.placeholderstyle}       selectedtextstyle={styles.selectedtextstyle}       inputsearchstyle={styles.inputsearchstyle}       iconstyle={styles.iconstyle}       search={data.length > 5}       maxheight={300}       searchplaceholder="search..."       data={data}       labelfield={labelfield}       valuefield={valuefield}       placeholder={!isfocus ? "select item" : "..."}       value={value}       onfocus={onfocus}       onblur={onblur}       onchange={onchange}     />   ); };  const styles = stylesheet.create({ // style props });  

zdropdown 是一个自定义组件。

样本数据

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",   }, ]; 

表单变量

我们使用 4 个状态变量,其中 3 个用于表单字段,其余一个用于触发焦点效果。

export default function app() {   const [country, setcountry] = usestate({     data: [],     selectedcountry: {},     value: null,   });   const [state, setstate] = usestate({     data: [],     selectedstate: {},     value: null,   });   const [city, setcity] = usestate({ data: [], selectedcity: {}, value: null });    const [ddfocus, setddfocus] = usestate({     country: false,     state: false,     city: false,   });    return (     <view style={styles.container}>       <view>         <text>country</text>         <zdropdown           data={country.data}           labelfield="name"           valuefield="countryid"           value={country.value}           isfocus={ddfocus.country}           onchange={null}         />         <text>state</text>         <zdropdown           data={state.data}           labelfield="name"           valuefield="stateid"           value={state.value}           isfocus={ddfocus.state}           onchange={null}         />         <text>city</text>         <zdropdown           data={city.data}           labelfield="name"           valuefield="cityid"           value={city.value}           isfocus={ddfocus.city}           onchange={null}         />       </view>       . . .     </view>   ); } 

焦点和模糊事件比 onchange 事件更容易被触发,因此对于焦点更改,这里使用一个单独的状态变量,以免弄乱下拉数据更改。

负载国家

从示例数据中加载国家/地区下拉列表。 (可以使用api调用

export default function app() { . . .   const loadcountry = () => {     // load data from api call     setcountry({ data: [...listcountry], selectedcountry: {}, value: null });   };    useeffect(() => {     loadcountry();   }, []);  return ( . . . ) 

对焦/模糊

当选择一个下拉菜单时,该字段必须被聚焦,而其余字段应该被模糊。我们正在使用一个函数来处理这个问题。

  const focusfield = (fld = '') => {     const obj = { country: false, state: false, city: false };     if (fld) obj[fld] = true;     setddfocus(obj);   }; 
        <text>country</text>         <zdropdown           . . .           isfocus={ddfocus.country}           onfocus={() => focusfield('country')}           onblur={() => focusfield('')}           onchange={null}         />         <text>state</text>         <zdropdown         . . .           isfocus={ddfocus.state}           onfocus={() => focusfield('state')}           onblur={() => focusfield('')}           onchange={null}         />         <text>city</text>         <zdropdown                 . . .           isfocus={ddfocus.city}           onfocus={() => focusfield('city')}           onblur={() => focusfield('')}           onchange={null}                /> 

React Native 的基本级联形式

我们现在已经完成了一半。

加载状态状态

在选择的国家/地区,我们需要根据所选国家/地区加载相应的 states。

更新国家/地区字段,根据国家/地区选择加载州并关注国家/地区。

  <text>country</text>   <zdropdown     . . .     onchange={(item) => {       setcountry({         ...country,         selectedcountry: item,         value: item.countryid,       });       loadstate(item.countryid);       focusfield("");     }}   /> 

当国家/地区发生变化时,州和城市都会发生变化。因此,在设置新值之前,我们需要清除现有数据。

const loadstate = async (cntid) => {   // load data from api call   setstate({ data: [], selectedstate: {}, value: null });   setcity({ data: [], selectedcity: {}, value: null });   const arr = listsate.filter((ele) => ele.countryid === cntid);   setstate({ ...state, data: [...arr] });   console.log("respective states ", arr); }; 

React Native 的基本级联形式

负载城市

并根据选择加载城市字段。

    <text>state</text>     <zdropdown       . . .       onchange={(item) => {         setstate({ ...state, selectedstate: item, value: item.stateid });         loadcity(item.stateid);         focusfield("");       }}      /> 
const loadcity = async (stid) => {   // load data from api call   setcity({ data: [], selectedcity: {}, value: null });   const arr = listcity.filter((ele) => ele.stateid === stid);   setcity({ ...city, data: [...arr] }); }; 

React Native 的基本级联形式

一切就绪,表单字段现在可以正常工作了。

React Native 的基本级联形式

如果我们再处理 2 个附加功能,我们就完成了。一种是休息页面,另一种是验证表单并显示警告。

重置页面

表单变量和焦点变量应该被清除。

. . . const resetform = () => {   focusfield("");   setcountry({ data: [...listcountry], selectedcountry: {}, value: null });   setstate({ data: [], selectedstate: {}, value: null });   setcity({ data: [], selectedcity: {}, value: null }); }; . . .    <touchableopacity onpress={() => resetform()} style={styles.clrbtn}>     <text style={styles.clrbtntxt}>reset</text>   </touchableopacity> . . .  

警告

如果父字段值为空,我们必须显示警告消息。为此,我们使用 paper 中的 snackbar 组件。

import { snackbar } from "react-native-paper";  export default function app() {   . . .   const [visible, setvisible] = usestate(false);   const [snackmsg, setsnackmsg] = usestate("");    const ontogglesnackbar = () => setvisible(!visible);   const ondismisssnackbar = () => setvisible(false);   . . .    return (     <view style={styles.container}>     . . .       <snackbar duration={2000} visible={visible} ondismiss={ondismisssnackbar}>         {snackmsg}       </snackbar>     </view>   ); }  

由于 state 和 city 字段有父字段,因此必须验证它们。

        <Text>State</Text>         <ZDropDown                     onFocus={() => {             focusField('state');             if (!country.value) {               setSnackMsg('Select country');               onToggleSnackBar();               focusField('country');             }           }}           . . .         />         <Text>City</Text>         <ZDropDown                     onFocus={() => {             focusField('city');             if (!country.value) {               setSnackMsg('Select country');               onToggleSnackBar();               focusField('country');             } else if (!state.value) {               setSnackMsg('Select state');               onToggleSnackBar();               focusField('state');             }           }}           . . .         /> 

React Native 的基本级联形式

是的,就是这样!我们完成了。谢谢。

完整代码参考这里

相关阅读