【问题标题】:React Native - Handling dynamic form depending on it's parent answerReact Native - 根据其父答案处理动态表单
【发布时间】:2019-01-08 07:07:36
【问题描述】:

我有一个使用 JSObject 的简单状态,状态如下:

pertanyaan: [{
    label: "label1",
    type: 'dropdown',
    key: 'keyFoo1',
    option: [{
        value: "foo1"
      },
      {
        value: "foo2",
        additional: {
          label: 'label1-1',
          type: 'date',
          key: 'keyFoo1-1',
          option:null
        }
      },
      {
        value: "foo3",
        additional:{
          label: 'label1-2',
          type: 'dropdown',
          key: 'keyFoo1-2',
          option:[
            {value:"Tidak ada orang"},
            {value:"Bertemu tetangga"},
          ]
        }
      },
    ]
  },
  {
    label: "Label2",
    type: 'dropdown',
    key: 'keyFoo2',
    option: [{
        value: "Rumah"
      },
      {
        value: "Tempat Kerja"
      },
    ]
  }
]

有了这些JSObject,我想根据每个父母的回答来实现某种形式,

示例:label1 有 3 个选项(foo1foo2foo3),如果label1 的答案是foo2,我需要渲染Date Component,如果label1 回答foo3 我需要渲染Dropdown Component

使用下面的代码,我可以用foo2 渲染label1 答案:

renderVisit(){
  var renderin = this.state.pertanyaan.map((item, index)=>{
    if(this.state[item.key] == undefined){
      this.setState({[item.key]:item.option[0].value})
    }
    let data = item.option.filter((val)=>{return val.value == this.state[item.key]})[0]
    return(
      <View>
        {/*dropdown Component*/}
        <View key={index}>
          <CustomText>{item.label}</CustomText>
          <Picker
            mode="dropdown"
            selectedValue={this.state[item.key]}
            onValueChange={(itemVal)=> this.onChangePicker(item, index, itemVal)}
          >
          {item.option.map((itemPicker, indexPicker)=>{
            return(
              <Picker.Item label={itemPicker.value} value={itemPicker.value} key={indexPicker} color={Color.blue_900}/>
            )
          })}
          </Picker>
        </View>
        {data!=undefined && data.additional!=undefined &&
          {/*dateComponent*/}
          <View>
            <CustomText>{data.additional.label}</CustomText>
            <TouchableOpacity onPress={()=>this.openDate(data.additional)}>
              <CustomText>{this.state[data.additional.key] == undefined? "Select Date" : new Date(this.state[data.additional.key]).toDateString()}</CustomText>
              <MaterialCommunityIcons name="calendar" size={34} />
            </TouchableOpacity>
          </View>
        }
      </View>
    )
  })
  return renderin
}

谁能帮助我实现我的目标并使代码更具可读性?

【问题讨论】:

  • 如果选择的值不是键而是整个对象的最佳方法,因此您可以使用该对象直接进行进一步渲染。
  • @gazdagergo key 用于定义状态,但我仍然坚持处理其父对象内的对象

标签: javascript reactjs react-native


【解决方案1】:

这就是我实现下拉组件动态选择的方式。您可以通过将组件本身作为另一个下拉列表的子级传递来递归地使用DropDown 组件;

const Date = () => 'Date Component';
const Foo = () => 'Foo';
const Bar = () => 'Bar';

class ListItem extends React.Component {
  handleClick = () => {
    const { option: {id}, onClick } = this.props;
    onClick(id);
  }
  
  render(){
    const { option: { label } } = this.props;
    return (
      <li onClick={this.handleClick}>{label}</li>
    )
  }
}

class DropDown extends React.Component {
  state = {
    selectedOption: null
  }
  
  handleOptionClick = optionId => {
    const { options } = this.props;
    this.setState({ selectedOption: options.find(option => option.id === optionId).child });
  }
  
  render(){
    const { selectedOption } = this.state;
    const { options } = this.props;
    return (
      <ul>
        {options.map(option => (
          <ListItem
            option={option}
            onClick={this.handleOptionClick}
          />
        ))}
        {selectedOption}
       </ul>
     )
  }
}

const DropDownOptions = [
  {id: '1', label: 'label-1', child: <Date />},
  {id: '2', label: 'label-2', child: <DropDown options={[
    {id: '2-1', label: 'label-2-1', child: <Foo />},
    {id: '2-2', label: 'label-2-2', child: <Bar />}
  ]} />}
]

ReactDOM.render(<DropDown options={DropDownOptions} />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

【讨论】:

  • 我的label-1 是下拉好友,
  • 是的,我无法在这里实现 react native 下拉菜单,只是想展示列表选择如何触发组件渲染的逻辑。
  • 我总是想递归让它工作,btw不需要递归函数吗?
  • 只需在下拉组件中使用与 App 中相同的逻辑即可 - 您会在其中获得另一个下拉列表。
猜你喜欢
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多