Контроллер компонентов на основе ввода массива (React native) - PullRequest
0 голосов
/ 21 февраля 2020

Я пытаюсь построить контроллер отчетов, где он направляет детализацию компонента на основе state.reports дочерних компонентов

Моя концепция такова

 1 - render the top level of array 
 2 - each array element is clickable and call function **route**
    - if element has children set state to child array and go to step 1
    - else go to detail page
 3 - if we are at child array we show **back button** that can return to previous render.   

Вот мой контроллер

export default class ReportControler extends React.Component {
  state = {reports: [] }

  componentWillMount() {
    this.parent = null;
    this.path = [this.constructor.name];
  }

  route = (report) =>{ 
    if(report.children) return this.moveToChild(report);
    this.props.navigation.navigate('ReportDetails', this.path.join('/') + '/' + report.title);
  }

  moveToChild = (report) => {
    this.parent = this.state.reports;
    this.path.push(report.title); 
    this.setState({reports: report.children});
  }

  moveToParent = () => { 
    this.setState({reports: this.parent});
    this.parent = null;
    this.path.pop();
  }

  render(){ 
    const reports = this.state.reports.map(report => (
      <TouchableWithoutFeedback onPress={() => { this.route(report) }} >
        <View><Box title={report.title} image={report.image} /></View>
      </TouchableWithoutFeedback >
    ));

    let back = null;
    if(this.parent){
      back = <TouchableWithoutFeedback onPress={this.moveToParent} >
        <View>
          <Text style={{color: '#274496', fontSize: 20, padding: 10, borderBottom: '#274496', borderBottomWidth: 2 }}>{this.path.join(' / ') }</Text>
        </View>
      </TouchableWithoutFeedback >
    }

    return(
      <View style={{flex: 1}}>
        {back}
        <View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
          {reports}
        </View>
      </View>
    );
  }
}

Дочерний компонент будет работать следующим образом

export default class Leads extends ReportController {
  state = {reports: [
        {title:"Campaign", image: require('../../assets/Report/bullhorn.png') },
        {title:"Status", image: require('../../assets/Report/analysis.png') },
        {title:"Source", image: require('../../assets/Report/wind-turbine.png') },
        {title:"Location", image: require('../../assets/Report/route.png') },
        {title:"Device", image: require('../../assets/Report/responsive.png') },
        {
          title:"Time", image: require('../../assets/Report/statistics.png'), 
          children: [
            {title:"Days", image: require('../../assets/Report/statistics.png')},
            {title:"Hours", image: require('../../assets/Report/statistics.png')},
          ]
        },
    ]
  }
}

Моя проблема сейчас связана с функцией возврата.
Эта функция не будет работать для более чем 2 уровня
Как установить this.parent массив?

moveToParent = () => { 
    this.setState({reports: this.parent});
    this.parent = null; //Here I should set the parent array  
    this.path.pop();
  }

1 Ответ

0 голосов
/ 21 февраля 2020

Мне пришлось исправить родителей, сохранив их в массиве

Вот что я сделал

  componentWillMount() {
    this.parents = [];
    this.path = [this.constructor.name];
  }
  moveToChild = (report) => {
    this.parents.push(this.state.reports);
    this.path.push(report.title); 
    this.setState({reports: report.children});
  }

  moveToParent = () => { 
    const reports = this.parents.pop();
    this.setState({reports});
    this.path.pop();
  }
...