Reactjs - 具有最少可能代码的条件相关下拉列表

问题描述 投票:1回答:1

我有一个带有工作相关下拉列表的React App。这是我的第一个React应用程序,我不认为我编码的方式是有效的。下面的代码工作正常,但我需要一些专家建议,因为我确信它效率很低。

基本上作为一个例子,当用户选择宗教为基督徒时,第二次下拉被触发,只有基督教中的种姓被显示在第二次下拉列表中。如果用户选择宗教为印度教,只会显示印度教的种姓等...

我是这样做的:

    import React, { Component } from 'react'
    ...
    import ReligionInput from './religion-input'
    import InputCasteChristian from './caste-christian-input'
    import InputCasteHindu from './caste-hindu-input'
    import InputCasteMuslim from './caste-muslim-input'
    ...
    class EditProfile extends Component {
      state = {
      ...
      ...
      religion,
      caste,
      ...
      render() {
       let {
      ...
      religion,
      caste,
      ...
      } = this.state

        //determine which caste to use
        let casteVariable
        let religionSelected = Object.values({ religion }).toString()
        switch (religionSelected) {
          case 'Christian':
            casteVariable = <InputCasteChristian value={caste} change={this.change} />            
break
          case 'Hindu':
            casteVariable = <InputCasteHindu value={caste} change={this.change} />
            break
          case 'Muslim':
            casteVariable = <InputCasteMuslim value={caste} change={this.change} />
            break
          default:
            casteVariable = ''
        }
    ...
    ...
    <div className="profile_right">
                  <div className="basic_details mb-3">
                    ...
                    ...
                    <ReligionInput value={religion} change={this.change} />
                    {casteVariable}

    const mapStateToProps = store => ({
      ud: store.User.user_details,
      tags: store.User.tags,
      session: store.User.session,
    })


    export default connect(mapStateToProps)(EditProfile)
    export { EditProfile as PureEditProfile }

这里是InputCasteChristian

import React from 'react'
import PropTypes from 'prop-types'
import Select from '../others/input/select'
import christianOptions from './caste-christian-options'

const InputCasteChristian = ({ value, change }) => (
  <div className="edit_caste_div">
    <Select
      placeholder="Select option"
      value={value}
      valueChange={e => change('caste', e)}
      className="edit_caste my2"
    >
      <option value="" disabled selected>
        Select Caste
      </option>
      {christianOptions.map((e, key) => {
       return <option key={key} value={e.value}>{e.name}</option>
       })}
    </Select>
  </div>
)

InputCasteChristian.propTypes = {
  value: PropTypes.string.isRequired,
  change: PropTypes.func.isRequired,
}

export default InputCasteChristian

我认为这不高效的主要原因是因为我正在为每个宗教创造一个组件 - 例如<InputCasteChristian

当我需要为州及其城市实施相同的逻辑时,我最终将为美国的每个州创建50个组件(例如)。

我使用MYSQL / PhpmyAdmin,我只有一个宗教专栏和一个用户选择的种姓专栏。没有查找表。

我使用Redux,因此将值存储在状态是一个选项。

什么是实现这一目标的替代和更有效的方法?

reactjs
1个回答
0
投票

尝试规范化商店内的数据。例如,考虑这样的结构:

const initialState = {
  selected: {
    state: null,
    city: null
  },
  states: {
    list: [0, 1, 2],
    entities: {
      0: {
        id: 0,
        name: 'state0',
        cities: [0, 3]
      },
      1: {
        id: 1,
        name: 'state1',
        cities: [1, 4]
      },
      2: {
        id: 2,
        name: 'state2',
        cities: [2, 5]
      }
    }
  },
  cities: {
    list: [0, 1, 2, 3, 4, 5],
    entities: {
      0: {
        id: 0,
        name: 'city0'
      },
      1: {
        id: 1,
        name: 'city1'
      },
      2: {
        id: 2,
        name: 'city2'
      }
      // ...
    }
  }
};

这样做有助于避免组件内部膨胀。基本上,您连接的容器应如下所示:

// ...

class Container extends Component {
  static propTypes = {
    selectState: PropTypes.func.isRequired,
    selectCity: PropTypes.func.isRequired,
    states: PropTypes.object.isRequired,
    cities: PropTypes.object.isRequired,
    selected: PropTypes.object.isRequired
  }

  get statesOptions () {
    return this.props.states.list.map(id => this.props.states.entities[id]);
  }

  get citiesOptions () {
    const { states, cities, selected } = this.props;
    const selectedStateCities = states.entities[selected.state].cities;

    return selectedStateCities.map(id => cities.entities[id]);
  }

  render () {
    return (
      <Fragment>
        <Select
          options={this.statesOptions}
          value={this.props.selected.state}
          onChange={({ id }) => this.props.selectState(id)}
        />
        <Select
          options={this.citiesOptions}
          value={this.props.selected.city}
          onChange={({ id }) => this.props.selectCity(id)}
        />
      </Fragment>
    );
  }
}

// ...

此外,要轻松规范化数据(尤其是API响应),请查看normalizr包。希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.