Реакция карты меняет номер индекса и нарушает условный рендеринг - PullRequest
0 голосов
/ 17 мая 2019

Я использую карту React для рендеринга некоторых слайдов в фиде на моем веб-сайте.Приведенная ниже функция берет данные, которые я собрал из Facebook Graph API, и переводит их в слайды для ползунка реагирования на мою страницу.

Первый слайд всегда должен быть моим компонентом, тогда как остальные должны бытьслайд с изображением и текстом.Я сделал это, сказав, что если index = 0, то визуализируем компонент.

Он работал нормально, но в последнее время он ломался, и я решил, что иногда первый слайд имеет индекс 1, а не 0.Я не уверен, почему это так, не должен ли первый слайд всегда иметь индекс 0?

renderSlides () {
  const { posts } = this.state
  const postsAvailable = posts.length > 0

  if (!postsAvailable) return null
  return posts.map((post, index) => {
    if (!post.message) return null
    return (
      <div key={post.id} ref={slider => (this.slider = slider)}>
        {index === 0 && <SliderItem />}
        {index >= 1 && (
          <div className='item'>
            <img
              data-fb={post.full_picture}
            />
            <div className={`item-content slide-${post.id}`}>
              <p className='text'>{post.message}</p>
            </div>
          </div>
        )}
      </div>
    )
  })
}

РЕДАКТИРОВАТЬ

Вот как я могу получить данные постов из facebook

downloadFBAPI () {
    window.fbAsyncInit = function () {
      FB.init({
        appId: appID,
        cookie: true,
        xfbml: true,
        version: 'v3.2'
      })
    }.bind(this);

    (function (d, s, id) {
      var js
      var fjs = d.getElementsByTagName(s)[0]
      if (d.getElementById(id)) return
      js = d.createElement(s); js.id = id
      js.src = '//connect.facebook.net/en_US/sdk.js'
      fjs.parentNode.insertBefore(js, fjs)
    }(document, 'script', 'facebook-jssdk'))
    SuperAgent
      .get('APIcall')
      .accept('application/json')
      .use(legacyIESupport)
      .end(this.getData)
  }

  getData (err, res) {
    if (err || !res || !res.body) {
      this.setState({
        isLoaded: true,
        err
      })
      return err
    } else {
      const result = res.body.data
      this.setState({
        isLoaded: true,
        posts: result
      })
    }
  }

1 Ответ

1 голос
/ 17 мая 2019

... иногда первый слайд имеет индекс 1, а не 0. Я не уверен, почему это ...

только причина этого в том, что массив, который вы вызываете map on (posts в вашем примере), представляет собой массив разреженный без записи с индексом 0. Пример:

const lower = [];
lower[1] = "one";
lower[2] = "two";
console.log(`'lower' has an entry at index 0? ${0 in lower}`);
console.log(`'lower' has an entry at index 1? ${1 in lower}`);
console.log(`'lower' has an entry at index 2? ${2 in lower}`);
console.log(`Mapping it:`);
const upper = lower.map((value, index) => {
    console.log(`index = ${index}`);
    return value.toUpperCase();
});
console.log(upper);
console.log(`'upper' has an entry at index 0? ${0 in upper}`);
console.log(`'upper' has an entry at index 1? ${1 in upper}`);
console.log(`'upper' has an entry at index 2? ${2 in upper}`);
.as-console-wrapper {
    max-height: 100% !important;
}

Вы можете получить разреженный массив, как минимум, тремя способами:

  1. Вы создали его таким образом (например,lower выше в примере выше);или
  2. (вариант # 1.) Вы создали его, используя map для массива, который был редок (например, upper в примере);или
  3. Вы использовали delete (или аналогичный) для удаления записи из массива (delete theArray[0];)

Причина в том, что map посещает только записи, которые существуют вмассив, он пропускает пробелы в разреженных массивах.Помните, что на уровне спецификации традиционные массивы JavaScript на самом деле не являются массивами ¹ (хотя они часто используются для оптимизации реализации), что означает, что вы можете иметь массив с length из 3, нотолько (например) две записи в нем.Это то, что lower выше (также upper).Или вы можете иметь еще больше пробелов:

const a = [];
a[3] = "three";
a[5] = "five";
logArray("a", a);
const b = a.map((value, index) => {
    console.log(`index = ${index}`);
    return value.toUpperCase();
});
logArray("b", b);

function logArray(name, a) {
    console.log(`${name}'s length is ${a.length}`);
    for (let index = 0; index < a.length; ++index) {
        console.log(`${name} has entry at index ${index}? ${index in a}`);
    }
}
.as-console-wrapper {
    max-height: 100% !important;
 }

Там, a и b не имеют записей для индексов 0, 1, 2 или 4.

Есливы устанавливаете length (или используете delete), у вас тоже могут быть пробелы в конце.


¹ (Это пост в моем маленьком анемичном блоге.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...