更新 React 中删除时显示的组件列表
Posted
技术标签:
【中文标题】更新 React 中删除时显示的组件列表【英文标题】:Update list of displayed components on deletion in React 【发布时间】:2019-08-07 10:33:09 【问题描述】:在我使用 React 的道路上,我正在创建简单的待办事项应用程序,用户可以在其中添加/删除基本上是独立组件的任务。
我使用以下方法创建任务:
addTask(taskObj)
let tasksList = this.state.tasksList;
tasksList.push(taskObj);
this.setState(tasksList : tasksList);
我使用以下方法呈现组件(任务)列表:
showTasks()
return (
this.state.tasksList.map((item, index) =>
return <SingleTask
taskObj=item
removeTask = (id) => this.removeTask(id)
key = index/>;
)
);
删除特定任务的方法将任务的唯一 ID 作为参数,并根据此 ID 从任务列表中删除它:
removeTask(uID)
this.setState(prevState => (
tasksList: prevState.tasksList.filter(el => el.id != uID )
));
但问题是,当我删除除最后一项之外的任何项目时,似乎实际的组件列表是相同的,只是将不同的对象传递给这些组件。
例如: 假设我有 2 个创建的组件,如果我在第一个上设置 state.Name = 'Foo',在第二个上设置 state.Name='Bar'。如果我单击第一个上的删除按钮,则与该组件关联的对象将被删除,第二个成为第一个但它的状态。名称现在是“Foo”而不是“Bar”。
我认为我在反应中缺少正确的创建/删除/显示组件。
编辑:
用于移除被点击组件的方法:
removeCurrentTask()
this.props.removeTask(this.props.taskObj.id);
SingleTask 组件:
class SingleTask extends Component
constructor(props)
super(props);
this.state=
showMenu : false,
afterInit : false,
id: Math.random()*100
this.toggleMenu = this.toggleMenu.bind(this);
toggleMenu()
this.setState(showMenu : !this.state.showMenu, afterInit : true);
render()
return(
<MDBRow>
<MDBCard className="singleTaskContainer">
<MDBCardTitle>
<div class="priorityBadge">
</div>
</MDBCardTitle>
<MDBCardBody className="singleTaskBody">
<div className="singleTaskMenuContainer">
<a href="#" onClick=this.toggleMenu>
<i className="align-middle material-icons">menu</i>
</a>
<div className=classNames('singleTaskMenuButtonsContainer animated',
'show fadeInRight' : this.state.showMenu,
'hideElement' : !this.state.showMenu,
'fadeOutLeft' : !this.state.showMenu && this.state.afterInit)>
<a
title="Remove task"
onClick=this.props.removeTask.bind(null, this.props.taskObj.id)
className=
classNames(
'float-right btn-floating btn-smallx waves-effect waves-light listMenuBtn lightRed'
)
>
<i className="align-middle material-icons">remove</i>
</a>
<a title="Edit title"
className=classNames('show float-right btn-floating btn-smallx waves-effect waves-light listMenuBtn lightBlue')
>
<i className="align-middle material-icons">edit</i>
</a>
</div>
</div>
this.props.taskObj.description
<br/>
this.state.id
</MDBCardBody>
</MDBCard>
</MDBRow>
);
在错误的视觉表示下,左侧的图像是删除前的图像,右侧是删除后的图像。虽然删除了带有“22”的卡片,但组件本身并没有被删除,只是传递了另一个对象。
【问题讨论】:
【参考方案1】:澄清一下,解决方案比预期的要简单。
在
const showTasks = () => taskList.map((item, index) => (
<SingleTask
taskObj=item
removeTask =removeTask
key = item.id
/>
)
)
我将 map index
作为键传递,当我将其更改为 item.id
时,一切正常。
【讨论】:
【参考方案2】:简而言之,在声明tasksList.push(<SingleTask taskObj=taskObj removeTask =this.removeTask/>);
中,removeTask = this.removeTask
应该变成removeTask = () => this.removeTask(taskObj.id)
。
但是,我会重新考虑方法 addTask
和 showTasks
的编写方式。虽然你写的方式没有错,但它在语义上是不正确的。这是我要做的:
addTask(taskObj)
let tasksList = this.state.tasksList;
tasksList.push(taskObj);
this.setState(tasksList : tasksList);
showTasks()
return (
this.state.tasksList.map((item, index) =>
return <SingleTask
taskObj=item
removeTask =() => this.removeTask(item.id)/>;
)
);
const SingleTask = (task) =>
const taskObj = task;
return <div onClick=task.removeTask>
taskObj.title
</div>
// Example class component
class App extends React.Component
state =
tasksList: [
id: 1, title: "One" ,
id: 2, title: "Two" ,
id: 3, title: "Three" ,
id: 4, title: "Four"
]
addTask = (taskObj) =>
let tasksList = this.state.tasksList;
tasksList.push(taskObj);
this.setState(tasksList : tasksList);
showTasks = () =>
return (
this.state.tasksList.map((item, index) =>
return <SingleTask
key=index
taskObj=item
removeTask =() => this.removeTask(item.id)/>;
)
);
removeTask(id)
this.setState(prevState => (
tasksList: prevState.tasksList.filter(el => el.id != id )
));
render()
return (
<div className="App">
<div> this.showTasks() </div>
</div>
);
// Render it
ReactDOM.render(
<App />,
document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
【讨论】:
感谢您的回复,但很遗憾您更改后的结果是一样的。 我不知道在哪里调用removeCurrentTask
,所以如果有帮助,我已经用代码 sn-p 更新了我的解决方案。
这样叫:<a title="Remove task" onClick=this.removeCurrentTask className= classNames( 'float-right btn-floating btn-smallx waves-effect waves-light listMenuBtn
反正结果是一样的。
我明白了。那么你原来的removeTask = this.removeTask
应该变成removeTask = (id) => this.removeTask(id)
。试试这个。
我已按照您的建议进行了所有更改,但结果仍然相同,组件并没有真正删除,只是列表中的特定对象。由于所有更改,我在原始帖子中编辑了方法。以上是关于更新 React 中删除时显示的组件列表的主要内容,如果未能解决你的问题,请参考以下文章