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()是因为