ReactNativeJS: Предупреждение: setState (): не может обновляться во время существующего перехода состояния (например, внутри `render`)

Я работаю над приложением React-Native \ Redux

  1. Я предварительно заполняю a по мере их рендеринга. Это прекрасно работает. 2.После заполнения я хотел бы вызвать действие отправки, чтобы значение каждого использовалось для выполнения некоторых вычислений, а затем для сохранения: я знаю, что невозможно обновить состояние во время рендеринга, но там, где я могу, добиться этого ?

Мне нужно, чтобы он обновлял состояние при создании полей ввода.

Любая помощь будет принята с благодарностью.

Спасибо

handleInputChange: function(product, productId, input){
let { currentSale, updateProductQuantity } = this.props;
let updatedCurrentSale = TransactionsService.updateProductQuantity(currentSale, product, productId, input);
let transaction = TransactionsService.packageTransaction(updatedCurrentSale);

updateProductQuantity(updatedCurrentSale, transaction)
 },

updateProductQuantity вызывает действие disaptch, и здесь возникает проблема.

handleQuantityValue: function(product, productId){
 let { orderSelected } = this.props;

  if(orderSelected){
     var index = orderSelected.products.findIndex(x => x.product_id==productId)
  }

  var i = index

  if( i >= 0){
      var qtty = orderSelected.products[i].product_quantity
      this.handleInputChange(product, productId, qtty).bind(this)
      return qtty.toString()
  }
  else{
        return ''
  }
},

возвращает значение количества

renderProducts: function(){
  let { currentUser, currentSale, orderSelected } = this.props;
  return _.map(currentSale.productSales, function(product, productId){
  var qtty = this.handleQuantityValue(product, productId)
  return <View style={Styles.questionPanel}>
    <Question 
      product={product}
      productId= {productId}
      Order={ orderSelected }
      quantity= { qtty }
      onInputChange={this.handleInputChange}
    />
  </View>
}.bind(this));

},

При этом отображаются продукты, и TextInput заполняется значением количество. Другое дело, что по мере его рендеринга я должен (не обязательно) отправить действие

render: function(){
 let { currentSale } = this.props;
 return (
  <View style={{flex: 1}}>
    <NavBar navigator={this.props.navigator} />
    <ScrollView>
      <Text style={[Styles.dayDisplayHeader, Styles.spacing]}>
        Enter Your Sale:
      </Text>
      {this.renderProducts()}
      <Calculator 
        productSales={currentSale.productSales}
        totalSales={currentSale.totalSales}
      />
      <Button text={'Save'} whenTapped={this.handleSubmit} />
    </ScrollView>
  </View>
)

person Ben Shiundu    schedule 13.10.2016    source источник
comment
Мне кажется, вы пытаетесь подойти к проблеме не с той точки зрения. Можете ли вы вставить код для своего компонента?   -  person Michał Szajbe    schedule 13.10.2016
comment
Я отредактировал свой вопрос   -  person Ben Shiundu    schedule 13.10.2016


Ответы (2)


Вы можете попробовать установить состояние (вам это разрешено) в методе componentDidUpdate: вам нужно только быть осторожным и определить, в какой ситуации вам нужно вызвать setState, чтобы избежать бесконечной рекурсии.

setState внутри componentDidUpdate

person pinturic    schedule 13.10.2016
comment
как я уже сказал, вы должны проявить мудрость и проверить в componentDidUpdate, когда обновлять состояние, а когда нет !! В идеале это нужно делать только один раз - person pinturic; 14.10.2016
comment
Я не понимаю, что у тебя действительно есть мой вопрос. - person Ben Shiundu; 22.10.2016

У вас есть рекурсия. Расчет значения количества запускает handleInputChange, который, в свою очередь, запускает расчет количества при повторной визуализации компонента.

Я не думаю, что вам даже нужно запускать handleInputChange вручную при вычислении значения количества. Вы не должны.

Поток должен быть таким:

  1. Передавать данные через реквизит.
  2. При рендеринге рассчитайте количество из реквизита.
  3. handleInputChange только когда значение изменено пользователем.
  4. После обновления хранилища redux (я предполагаю, что это происходит через updateProductQuantity) новые значения будут снова переданы компоненту через реквизиты (вернитесь к шагу 1).
person Michał Szajbe    schedule 17.10.2016
comment
Это то, чем я занимаюсь сейчас, хотел, чтобы это было сделано прагматично. Допустим, когда продажа осуществляется курьером, которому нужно просто подтвердить продажу, но также с возможностью добавить больше продуктов в список, если это необходимо. Я пока буду придерживаться их. Спасибо. - person Ben Shiundu; 22.10.2016