我有一个带有工作相关下拉列表的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,因此将值存储在状态是一个选项。
什么是实现这一目标的替代和更有效的方法?
尝试规范化商店内的数据。例如,考虑这样的结构:
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包。希望能帮助到你。