【问题标题】:React map changes index number and breaks conditional renderingReact map 更改索引号并中断条件渲染
【发布时间】:2019-10-04 17:36:25
【问题描述】:

我正在使用 React 地图在我网页上的 facebook 提要中呈现一些幻灯片。下面的函数获取我从 Facebook Graph API 收集的数据,并将它们呈现为我页面上 react-slick 滑块的幻灯片。

第一张幻灯片应该始终是我的组件,然后其他幻灯片应该是带有图像和文本的幻灯片。我通过说如果 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
      })
    }
  }

【问题讨论】:

  • 粘贴您的帖子对象。

标签: javascript reactjs facebook-graph-api


【解决方案1】:

...有时第一张幻灯片的索引为 1,而不是 0。我不确定这是为什么...

发生的唯一原因是如果您调用 map 的数组(在您的示例中为 posts)是一个 sparse 数组,索引处没有条目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 的传统数组 aren't really arrays¹(尽管它们通常作为实现优化),这意味着您可以拥有一个包含 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),你也可以在末尾有间隙。


¹ (这是我贫血的小博客上的一篇文章。)

【讨论】:

  • 我将帖子定义为类似posts=[]的状态,我应该以不同的方式执行此操作吗?有时索引为 0,有时为 1,但并不总是 1。
  • @user3005003 - posts = [] 很好(用于创建空数组)。问题是,在这样做之后,要么您没有填写索引 0 处的条目(如上面的实时示例),要么您正在填写但稍后将其删除。
  • 问题:如果你按照上面的方法做,但是从lower[5] = 'one'开始,索引会从什么开始?
  • @ColinRicardo - 5,因为map 只访问存在于数组中的条目。 JavaScript 的传统数组 aren't really arrays at all(在我非常贫血的博客上发帖)。如果您执行const a = []; a[5] = "five";,则您创建了一个数组,其中length 设置为6(比最高索引高一个),索引0-4 处根本没有条目,索引5 处有一个条目。调用map它只会调用一次map 的回调,其值为"five",索引为5。
猜你喜欢
  • 2020-09-14
  • 2021-05-22
  • 1970-01-01
  • 2019-10-05
  • 2018-10-01
  • 1970-01-01
  • 2021-06-07
  • 1970-01-01
  • 2019-01-02
相关资源
最近更新 更多