React Native-根据其父答案处理动态表单

时间:2019-01-08 07:07:36

标签: javascript reactjs react-native

我使用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的答案是foo1foo2有3个选项(foo3label1foo2)渲染Date Component,如果label1回答foo3,我需要渲染Dropdown Component

使用下面的代码,我只能使用label1的答案来渲染foo2

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
}

任何人都可以帮助我实现我的目标并使代码更具可读性吗?

1 个答案:

答案 0 :(得分: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>