按钮删除列表项并更改其ordning |应对

时间:2017-09-25 11:44:20

标签: javascript reactjs

我有一个按钮,按下它时应该切换列表中的更多项目。我在构造函数中设置了默认状态:

constructor(props) {
  super(props)
  this.state = {
    showCount: 10,
    expanded: false
  }
}

因此,列表中的默认项目数为10,并且未展开。然后我创建了一个应该更改状态并加载更多列表项的函数:

loadMore() {
  const { showCount } = this.state
  const { events } = this.props
  showCount === 10
    ? this.setState({ showCount: events.reverse().length, expanded: true })
    : this.setState({ showCount: 10, expanded: false })
}

创建一个"按钮"如果expanded状态为真或假,则应该更改它的文本:

const toggleMore = (
  <div className="text-center">
    <a className="show-more" onClick={() => this.loadMore()}>
      {this.state.expanded ? (
        <span>Visa mindre</span>
      ) : (
        <span>Visa mer</span>
      )}
    </a>
  </div>
)

然后使用带有.slice变量的showCount的列表项组件:

const mappedEvents =
  events.length === 0 ? (
    <p style={{ textAlign: 'center' }}>No events</p>
  ) : (
    events
      .reverse()
      .slice(0, this.state.showCount)
      .map((event, i) => {
        return (
          <div>
            <EventItem
              key={i}
              ...
            />
          </div>
        )
      })
  )

我的问题

所以这个按钮在我第一次使用时效果很好。如果我来到我的页面,我可以看到所有10个列表项,按下按钮时文本会发生变化。 当我再次按下它时(expanded: true)我的所有列表项消失。当我第三次按下它时,我的列表项的顺序发生了变化,这意味着.revers()显然不再有效了。当我第四次按它时,它会回到第一阶段; 10个列表项和ordning是应该的。之后,它不断重复。

所以我只想知道我在这里做错了什么以及为什么按钮就像这样。

感谢阅读!

2 个答案:

答案 0 :(得分:2)

基本问题是events.reverse()是破坏性的,它实际上变异原始数组,它不会简单地返回一个新的反向数组。这个阵列来自道具这也是一个问题 - 你绝对不应该修改来自道具的东西,你不知道父组件是否会在以后用新阵列覆盖它。

此外,如果您在渲染过程中使用reverse(),请记住渲染可能会运行一堆您可能会意识到的更多次。每次渲染它都会再次反转阵列。

我在这里建议的只是在渲染过程中执行数组变换,并以非破坏性方式执行。获得新的反向数组的一种方法是首先使用切片创建一个副本,然后然后将其反转,如下所示:

const reversed = events.slice().reverse();

另外我注意到你正在使用events.reverse().length - 可能这与events.length相同,你需要在这里改变数组吗?

答案 1 :(得分:0)

我取下了倒车部件,我不确定你到底需要它。并将这些功能分解为单独的方法,甚至是单独的小组件。

以下是代码:

import React, { Component } from 'react';
import { render } from 'react-dom';

class App extends Component {
  render() {
    return (
      <List events={[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]} />
    );
  }
}

class List extends Component {
  constructor(props) {
    super(props)
    this.state = {
      showCount: 10,
      expanded: false
    }
    this.renderMappedEvents = this.renderMappedEvents.bind(this);
    this.renderToggleMoreBtn = this.renderToggleMoreBtn.bind(this);
  }

  loadMore() {
    const { showCount } = this.state
    const { events } = this.props
    showCount === 10
      ? this.setState({ showCount: events.length, expanded: true })
      : this.setState({ showCount: 10, expanded: false })
  }

  renderMappedEvents() {
    const { events } = this.props; 
    return events.length === 0 ? (
    <p style={{ textAlign: 'center' }}>No events</p>
    ) : (
      events
        .slice(0, this.state.showCount)
        .map((event, i) => {
          return (
            <div>
              { event }
            </div>
          )
        })
    )
  }

  renderToggleMoreBtn() {
    return (
      <div className="text-center">
        <a className="show-more" onClick={() => this.loadMore()}>
          {this.state.expanded ? (
            <span>Visa mindre</span>
          ) : (
            <span>Visa mer</span>
          )}
        </a>
      </div>
    );
  }

  render() {
    return (
      <div>{[
        this.renderMappedEvents(),
        this.renderToggleMoreBtn()
      ]}</div>);
  }

}

render(<App />, document.getElementById('root'));

指向工作代码段的链接: https://stackblitz.com/edit/react-kmdz9f