Изображение из облачного хранилища не отображается в списке .map - PullRequest
0 голосов
/ 16 октября 2018

Я создаю список сообщений в .map, извлекаемых из моего Firebase Cloud Firestore.У меня также есть фотографии, соединяющиеся с каждым постом, и я получаю их, используя post.title + '.jpg' из облачного хранилища.Заголовок сообщения получился великолепным, но при использовании fetchImage он не отображается в сообщении.Это отображается в console.log.Я также могу получить доступ к URL из консоли, так что ничего плохого там нет.

Есть идеи?

{this.state.posts.map((post, i) => {
  let fetchImage
  firebase
  .storage()
  .ref(post.title + '.jpg')
  .getDownloadURL()
  .then((url) => {
    console.log(url)
    fetchImage = url;
  });
  return (
    <Text>{post.title}</Text>
    <Image
      style={styles.image}
      source={{
      uri: fetchImage
      }}
    />
  )}
)}

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

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

Типичным способом извлечения внешних ресурсов в компоненте React является использование синтаксиса класса Component / PureComponent, отправка запроса на выборку в хуке componentDidMount и сохранение данных, возвращаемых обещанием в состоянии (используя this.setState).

Функция рендеринга должна отображаться на основе значений в состоянии - чтобы после обновления состояния с извлеченным значением компонент выполнял повторный рендеринг с использованием извлеченных данных.

0 голосов
/ 16 октября 2018

Что такое свойство ReactJS this.props.items.map?

Это должно помочь вам понять принципы использования метода «map» для обхода и отображения спискапохожих объектов, представляющих компонент в ReactJS.Заголовок «this.props.items.map» может быть любым другим методом карты, например «this.props.profiles.map», в котором ниже приведены примеры, где профили или элементы представляют массив.Его можно использовать для создания списка, таблицы и т. Д.

Вот основные положения этой статьи:

  • Карта НЕ является функцией ReactJS
  • Посмотрите пример кода с использованием «map» в контексте this.props.profiles.map

После просмотра учебника, представленного на этой ReactJS tutorials странице, где есть ссылка.Карта создана для отображения объектов комментариев, можно запутаться и подумать, что «карта» - это функция ReactJS.На самом деле это стандартная функция JavaScript, которую можно вызывать для любого массива

Если вы работали с такими языками, как Python (метод apply) или R (метод lapply), вы, вероятно,использовал «map» в качестве метода для передачи функции с параметром, представляющим ссылку на объект, хранящийся в массиве.Когда вызывается «map», функция применяется к каждому из объектов, хранящихся в массиве.«Карта» возвращает новый массив, состоящий из объектов, которые могут быть созданы с использованием объектов переданного массива

Общий синтаксис: array.map(func)

, где func должен принимать один параметр.

Как упомянуто в тексте выше, возвращаемым значением array.map является другой массив.

Пример кода с использованием «map» в контексте this.props.profiles.map

В приведенном ниже примере обратите внимание на некоторые из следующих вещей:

  • Существует два компонента, такие как UserProfiles и Profile
  • Компонент профиля используется для представления фактического профиля, состоящего из атрибутов имени и страны.
  • UserProfiles, как это звучит, используется для представления одного или нескольких профилей и визуализации компонентов профиля.
  • Обратите внимание, что UserProfiles передается объект json, такой как profileJson, который состоит из профилей, представленных в формеобъекта JSON.
  • В методе рендеринга UserProfiles отображается переменная «allProfiles», созданная с помощью «map»метод.Метод «map», в свою очередь, возвращает массив Profile.

Ниже показано, как приведенный ниже пример кода будет отображаться в HTML:

<div id="content"></div>
<script type="text/jsx">
var profilesJson = [
{name: "Pete Hunt", country: "USA"},
{name: "Jordan Walke", country: "Australia"}];
var Profile = React.createClass({
render: function(){
          return(
              <div>
<div>Name: {this.props.name}</div>
<div>Country: {this.props.country}</div>
<hr/>
     </div>
);
    }
});
var UserProfiles = React.createClass({
render: function(){
var allProfiles = this.props.profiles.map(function(profile){
return (
<Profile name={profile.name} country={profile.country} />
);
});
return(
<div>{allProfiles}</div>
);
}
});
React.render( <UserProfiles profiles={profilesJson}/>, document.getElementById( "content"));</script>
0 голосов
/ 16 октября 2018

URL-адрес загрузки загружается асинхронно.Чтобы увидеть, что это значит, поместите несколько операторов журнала:

console.log("Before calling getDownloadURL")
firebase
.storage()
.ref(post.title + '.jpg')
.getDownloadURL()
.then((url) => {
  console.log("Got URL")
});
console.log("After calling getDownloadURL")

При запуске этого кода вы получаете:

Перед вызовом getDownloadURL

После вызова getDownloadURL

Получил URL

Вероятно, это не тот порядок, в котором вы ожидали вывод. Но это полностью объясняет, почему ваш return не возвращает URL загрузки: он не былзагружен еще.

Обратный вызов then() из вашего звонка на getDownloadURL запускает после вас return компонента, который использует uri: fetchImage.И вы не можете вернуть значение, которое еще не загружено.

Распространенным решением в React является хранение любых данных, которые асинхронно загружаются в состояние компонента.

this.state.posts.map((post, i) => {
  let fetchImage
  firebase
  .storage()
  .ref(post.title + '.jpg')
  .getDownloadURL()
  .then((url) => {
    let state = {};
    state[post.title+"_url"] = url
    this.setState(state)
  });
})

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

return (
  <Text>{post.title}</Text>
  <Image
    style={styles.image}
    source={{
    uri: this.state[post.title+"_url"]
    }}
  />
...