2016-06-14 2 views
1

Я использую React с сервером Flask и имею таблицу, в которой пользователь может вводить информацию. Этот ребенок таблица обновляет tableData состояние MainApp, когда пользователь редактирует ячейку, добавляет новую строку, удаляет строку и т.д.Как использовать React to setState и избежать рекурсии?

Моя проблема заключается в том, что я использую image состояние в MainApp для хранения URL изображения (этот URL также содержит хеш, поэтому он изменяется каждый раз, когда клиент запрашивает информацию). Тем не менее, я также использую состояние tableData в MainApp для хранения информации таблицы, которая изменяется, когда пользователь обновляет таблицу. Это вызывает componentWillUpdate, который, в свою очередь, получает изображение blob, преобразует его в URL-адрес и обновляет состояние image. Это, в свою очередь, вызывает componentWillUpdate, как вы можете себе представить, что приведет к рекурсивному звонку. React documentation говорит, чтобы не звонить setState внутри componentWillUpdate. Мне любопытно, какой рекомендуемый способ сделать это.

Предполагаемое поведение заключается в том, что пользователь редактирует ячейку таблицы, MainApp отправляет запрос на сервер с информацией о таблице, MainApp получает изображение и соответственно обновляет страницу. Должен ли я не использовать состояние image для хранения URL-адреса?

Один из способов сделать это состоит в использовании setState в componentWillUpdate и использовать shouldComponentUpdate с логикой на основе GlobalVariable (shouldComponentUpdate будет вызываться несколько раз), но я уверен, что это, вероятно, не рекомендуемый подход.

var globalVariable = true 
var MainApp = React.createClass({ 
    shouldComponentUpdate : function() { 
    // logic here using globalVariable 
    } 
    componentWillUpdate : function() { 
     console.log("Get image from server") 
     fetch('/api/data', { 
     method: 'POST', 
     body: JSON.stringify({ 
        tableData: this.state.tableData, 
     }) 
     }) 
      .then(function(response) { 
       return response.blob(); 
      }.bind(this)) 
      .then(function(imageBlob) { 
       this.setState({ 
        image: URL.createObjectURL(imageBlob), 
        tableData: this.state.tableData 
       }) 
      }.bind(this)) 
     }, 
    handleTableUpdate : function(newState) { 
      this.setState({ 
       image: this.state.image, 
       tableData: newState 
      }); 
      console.log("Table updated") 
     }, 
    render : function() { 
     return (
      <div> 
       <div id="inverter-table" className="col-sm-6"> 
        <MyReactBootstrapTable 
          onTableUpdate={this.handleTableUpdate} 
          data={this.state.tableData} /> 
       </div>     
       <div id="img" className="col-sm-6"> 
        <MyPlot url={this.state.image}></MyPlot> 
       </div> 
      </div> 
      ); 
     } 
    }) 
+0

Почему вы не вызываете вызов 'fetch' внутри' handleTableUpdate'? – FaureHu

+0

Это сработало бы! Мне было просто интересно, как лучше реагировать на практику. Если у вас есть предложения, которые были бы замечательными. – kdheepak

ответ

0

Вы можете определить измененное свойство в компонентеWillReceiveProps, а затем вызвать setState соответственно. Это не приведет к рекурсии в коде.