Как вызвать рендер в React Native после успешного извлечения данных API - PullRequest
1 голос
/ 31 января 2020

Я новичок в React Native и у меня возникли проблемы с заполнением опций выпадающего меню.

Прежде чем вы скажете, что это дублирующий вопрос - вот ссылка на вопрос, который Спросили 3 года go, где они обсуждали, как заполнить раскрывающийся список, используя массивы и списки.

Я использую карту, которая представляет собой структуру данных, введенную в JS в ES6.

Я использую Picker для раскрывающегося списка.

Я заполняю карту с именем branchData данными, полученными с помощью REST API.

вот мой код для заполнения раскрывающегося списка:

<Picker
            selectedValue={this.state.branch}
            style={styles.fieldPicker}
            mode="dropdown"

            onValueChange={(itemValue, itemIndex) =>
              this.setState({branch: itemValue})
            }>

            {/* Data Binding */}

                {this.state.branchData.forEach((name, id) => 
                      {
                      return <Picker.Item key={id} value={id} label={name} />;
                      })
                }



          </Picker>

Я проверил правильность доступа к имени и идентификатору, войдя в него по нажатию кнопки.

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

Ранее я вручную добавил два элемента выбора и смог видеть их при нажатии.

ОБНОВЛЕНИЕ:

Вопрос, который я s, что функция рендеринга вызывается до того, как API сможет извлечь детали и обновить переменную состояния

Таким образом, раскрывающийся список пуст, но в файле console.log, который вызывается при нажатии кнопки, отображаются данные. (дай знать, если ты хочешь увидеть код)

Я добавил вызов API в конструкторе, предполагая, что он будет выполнен перед рендерингом, но вызов API, являющийся асинхронным, не происходит до рендеринга .

Короче говоря - Как вызвать render после того, как API успешно выберет данные?

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Обходной путь, который я получил:

Внутри Конструктора:

  • Установите логическое значение "isLoading" равным true.

Внутри функции componentDidMount:

  • Напишите код выборки данных и измените логическое значение «isLoading» на «ложь» после загрузки данных.

ДОПОЛНИТЕЛЬНО - Внутри рендеринга:

  • Есть блок if else, который возвращает два разных блока в зависимости от значения "isLoading"

Например, вы можете иметь:

if(this.state.isLoading)
{
  return(
  <View>
  <ActivityIndicator/>
  </View>
  )
}

, который показывает круг загрузки при получении данных. В противном случае вы можете go опередить без блока if else, единственное, что выпадающие списки заполняются внезапно и могут выглядеть не очень хорошо.

- тем самым повторно отображать экран и заполнять данные в раскрывающемся списке после их извлечения.

Я знаю, что может быть более оптимальное решение, но это то, что я получил на данный момент.

Но Можно спросить, как это работает?

Повторная визуализация может быть запущена только в том случае, если состояние компонента изменилось.

Состояние может изменяться в зависимости от смены реквизита или прямого изменения setState.
Компонент получает обновленное состояние, и React решает, следует ли ему повторно выполнить рендеринг компонента. К сожалению, по умолчанию React невероятно упрощен c и в основном все время перерисовывает все.

Полный текст статьи здесь .

Если вы делаете найти лучшее решение для рендеринга, пожалуйста, дайте мне знать. Из-за этого подхода все может стать сложнее, если у нас есть раскрывающийся список, который заполняется на основе ранее выбранной опции.

ОБНОВЛЕНИЕ:

Я нашел красивый блог , который объясняет жизненный цикл компонентов и где следует вызывать API, а где нет. Проверьте это и проигнорируйте моё предложение о нубе выше.

0 голосов
/ 31 января 2020

Обычно реагирующие компоненты не перерисовываются при изменении массива, чтобы избежать многих перерисовок. Одним из обходных путей является принудительное повторное рендеринг компонента путем подделки нового компонента путем изменения ключа компонента:

<Picker
  key={`myPicker_${this.state.branchData.length}`} //HERE
  selectedValue={this.state.branch}
  style={styles.fieldPicker}
  mode="dropdown"
  onValueChange={(itemValue, itemIndex) =>
    this.setState({branch: itemValue})
  }>
    {this.state.branchData.forEach((name, id) => {
        return <Picker.Item key={id} value={id} label={name} />;
    })}
</Picker>

По сути, каждый раз, когда вы получаете новую длину для массива this.state.branchData Сборщик получит новый Ключ. Если старая длина! = Новая длина, она будет действовать как новый компонент и будет перерисована.
Обратите внимание, что длина массива может быть простым решением, но, вероятно, не лучшим (та же длина = без повторного отображения). render)

Я не уверен, что это решит ваши проблемы, но стоит попробовать

...