Реагировать на собственную загрузку данных вне конструктора

I’m just getting the hang of react-native but really getting stuck on Scenario #2 and #3. Это может быть поздний час, но я не могу просто заставить listview повторно заполняться вне конструктора сцены…

Примечание: это простой пример, который в конечном итоге станет более продвинутой загрузкой данных

Сценарий #1 привязка в контроллере

Это работает отлично:

export default class HomeView extends Component {
  constructor(props)
  {
    super(props);

    const ds = new ListView.DataSource(
      {
        rowHasChanged: (r1,r2) => r1 !== r2
      }
    );

    var data = [
        {"id":1, "desc": "Some description of a request", "group": "Today"},
        {"id":2, "desc": "Another description of a request", "group": "Today"} 
      ];

    this.state = {
      loaded: false,
      data: data,
      dataSource: ds.cloneWithRows(data)
    };

Сценарий #2-метод загрузки вызова

Это подмножество запускается из конструктора. Когда я вызываю метод напрямую, он выдает ошибку «вызов setState на размонтированном компоненте является проблемой». Справедливо, но это делает весь метод и запускает два консольных оператора. Я пытался решить эту проблему в #3.

    var data = [
        {"id":1, "desc": "Some description of a request", "group": "Today"},
        {"id":2, "desc": "Another description of a request", "group": "Today"} 
      ];

    this.state = {
      loaded: false,
      data: data,
      dataSource: ds
    };

     console.log("About to load data");
     this.loadData();
   } //end ctor

   loadData() {
     console.log("Data count is: " + this.state.data.length);

     this.setState({
        dataSource: this.state.dataSource.cloneWithRows(this.state.data),
        loaded     : true
     });
   }

Сценарий #3 — Использование Bind

Использование метода Bind () для LoadData просто оставляет пустой экран без появления инструкций logging, поэтому он поливается другим способом. Код запускается из конструктора…

 var data = [
    {"id":1, "desc": "Some description of a request", "group": "Today"},
    {"id":2, "desc": "Another description of a request", "group": "Today"} 
  ];

 this.state = {
   loaded: false,
   data: data,
   dataSource: ds
 };

  console.log("About to load data");
   this.loadData = this.loadData.bind(this);
} //end ctor

loadData() {
   console.log("Data count is: " + this.state.data.length);

   this.setState({
     dataSource: this.state.dataSource.cloneWithRows(this.state.data),
     loaded     : true
   });
}

Как это сделать?

2 ответа

  1. используйте ключевое слово const и объявите вне класса

    const data = [
            {"id":1, "desc": "Some description of a request", "group": "Today"},
            {"id":2, "desc": "Another description of a request", "group": "Today"} 
          ];
    
  2. Я думал, что я пробовал его раньше, но, очевидно, я не использовал его правильно. Сцена имеет несколько встроенных методов, которые можно использовать: componentWillMount()выполняется перед render()вызовом метода, перед монтированием компонента и componentDidMount()выполняется после render () и после монтирования, поэтому это componentDidMount()теперь работает:

    componentDidMount() {
        var data = [
            {"id":1, "desc": "Some description of a request", "group": "Today"},
            {"id":2, "desc": "Another description of a request", "group": "Today"} 
          ];
    
        console.log("Loading data...");
    
        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(data),
            loaded     : true
        });
      }