Javascript 按钮删除列表项并更改其排序|反应

Javascript 按钮删除列表项并更改其排序|反应,javascript,reactjs,Javascript,Reactjs,我有一个按钮,当按下它时,应该可以切换列表中的更多项目。我在构造函数中设置了默认状态: constructor(props) { super(props) this.state = { showCount: 10, expanded: false } } 因此,列表中的默认项目数将为10,并且不会展开。然后,我创建了一个函数,用于更改状态并加载更多列表项: loadMore() { const { showCount } = this.state const

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

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 })
}
并创建了一个“按钮”,如果
已扩展的
状态为true或false,则该按钮应更改其文本:

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>
)
我的问题 所以这个按钮在我第一次使用的时候效果很好。如果我来到我的页面,我可以看到所有的10个列表项,当按下按钮时,文本会发生变化但是当我第二次按它时(当
展开时:true
),我的所有列表项都会消失。当我第三次按它时,列表项的顺序会改变,这意味着
.reverse()
显然不再有效。当我第四次按下它时,它会回到第一阶段;列出10个项目,并按其应有的顺序排列。在那之后,它只是不断重复

所以我只想知道我做错了什么,为什么按钮会这样


谢谢你的阅读

基本问题是events.reverse()是破坏性的,它实际上是对原始数组的变异,而不是简单地返回一个新的反转数组。这个数组来自props,这也是一个问题——您绝对不应该修改来自props的内容,您不知道父组件是否会稍后用新数组覆盖它

另外,如果在渲染过程中使用reverse(),请记住,渲染可能会比您意识到的运行更多的次数。每次渲染时,它都会再次反转数组

我在这里建议只在渲染期间执行阵列变换,并以非破坏性的方式执行操作。获取新反转数组的一种方法是首先使用slice创建一个副本,然后将其反转,如下所示:

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

另外,我注意到您使用的是
events.reverse().length
——这可能与events.length相同,您需要在这里变异数组吗?

基本问题是events.reverse()是破坏性的,它实际上变异了原始数组,而不是简单地返回一个新的反转数组。这个数组来自props,这也是一个问题——您绝对不应该修改来自props的内容,您不知道父组件是否会稍后用新数组覆盖它

另外,如果在渲染过程中使用reverse(),请记住,渲染可能会比您意识到的运行更多的次数。每次渲染时,它都会再次反转数组

我在这里建议只在渲染期间执行阵列变换,并以非破坏性的方式执行操作。获取新反转数组的一种方法是首先使用slice创建一个副本,然后将其反转,如下所示:

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

另外,我注意到您使用的是
events.reverse().length
——这可能与events.length相同,您是否需要在此处对数组进行变异?

我将删除反转部分,我不确定您最终是否需要它。并将这些常量提取到单独的方法中,甚至是单独的小组件中

代码如下:

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'));
import React,{Component}来自'React';
从'react dom'导入{render};
类应用程序扩展组件{
render(){
返回(
);
}
}
类列表扩展组件{
建造师(道具){
超级(道具)
此.state={
演出人数:10,
扩展:false
}
this.renderAppedEvents=this.renderAppedEvents.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})
}
渲染外观(){
const{events}=this.props;
return events.length==0(

无事件

) : ( 事件 .slice(0,此.state.showCount) .map((事件,i)=>{ 返回( {event} ) }) ) } renderToggleMoreBtn(){ 返回(

我会移除反转部分,我不确定你最终是否需要它。然后将这些常量提取到单独的方法中,甚至是单独的小组件中

代码如下:

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'));
import React,{Component}来自'React';
从'react dom'导入{render};
类应用程序扩展组件{
render(){
返回(
);
}
}
类列表扩展组件{
建造师(道具){
超级(道具)
此.state={
演出人数:10,
扩展:false
}
this.renderAppedEvents=this.renderAppedEvents.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})
}
渲染外观(){
const{events}=this.props;
return events.length==0(

无事件

) : ( 事件 .slice(0,此.state.showCount) .map((事件,i)=>{ 返回( {event} ) }) ) } renderToggleMoreBtn(){ 返回(

试试
onClick={this.loadMore.bind(this)}
@ChrisG感谢您的回复。尝试了但没有成功:(嗨,有几个问题:1)请您解释一下,为什么使用反向?我看不懂提供的代码。2)您在哪里定义toggleMore和mappedEvents常量?我构建的这个似乎可以工作。@GlebKost是的,我使用reverse()是因为