我很反应。我坚持用onClick按钮从屏幕上移除卡片。从这一点开始,我可以得到this.props.data,如果我是console.log(this.props.data),它会返回给我
(2) [Object, Object]
0: Object
1: Object
所以我想知道如何从this.props.data
中删除对象。当我使用带有索引的splice
方法(实际上是对象的id)时,this.props.data.splice(index, 1)
它无法正常工作,但是项目从屏幕上消失了。这个函数从头到尾按顺序删除数组中的所有内容。请解释我如何才能获得最佳解决方案。
这是代码:
import React from "react";
import TaskList from './TaskList';
import update from 'immutability-helper';
import './../stylesheets/main.scss';
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {};
localStorage.getItem("tasks") ? (this.state.tasks = JSON.parse(localStorage.tasks)) : (this.state.tasks = []);
}
addTask(id) {
const newTasks = this.state.tasks;
let task = {type: 'do_it', id: '0', description: '', priority: '', time: new Date().toLocaleString()};
let desc = document.getElementById("description").value;
let cardPriority = document.getElementById("priority-selector").value;
task.id = newTasks.length + 1;
task.description = desc;
task.priority = cardPriority;
newTasks.push(task);
localStorage.setItem('tasks', JSON.stringify(newTasks));
this.setState({
tasks: newTasks
})
}
handleDrop(id, toType) {
const tasks = this.state.tasks;
const taskIndex = tasks.findIndex((task) => {
return task.id == id;
});
const updatedTask = update(tasks[taskIndex], {type: {$set: toType}});
const newTasks = update(tasks, {
$splice: [[taskIndex, 1, updatedTask]]
});
localStorage.setItem('tasks', JSON.stringify(newTasks));
this.setState({tasks: newTasks});
}
render() {
return (
<div className="page-home">
<div className="input">
<div className="inner">
<h1>Kanban Board</h1>
<input name="description" type="text" id="description"/>
<select name="priority" id="priority-selector">
<option value="">Priority:</option>
<option value="1">1: High</option>
<option value="2">2: Medium</option>
<option value="3">3: Low</option>
</select> <br/>
<button type="submit" className="submit" onClick={this.addTask.bind(this)}>Add task</button>
</div>
</div>
<div className="container">
<div className="column">
<h2>Do it</h2>
<TaskList
data={this.state.tasks}
type={'do_it'}
/>
</div>
<div className="column">
<h2>In Progress</h2>
<TaskList
data={this.state.tasks}
type={'in_progress'}
allowedTypes={['do_it']}
handleDrop={this.handleDrop.bind(this)}
/>
</div>
<div className="column">
<h2>Done</h2>
<TaskList
data={this.state.tasks}
type={'done'}
allowedTypes={['in_progress']}
handleDrop={this.handleDrop.bind(this)}
/>
</div>
<div className="column">
<h2>Aborted</h2>
<TaskList
data={this.state.tasks}
type={'aborted'}
allowedTypes={['do_it', 'in_progress']}
handleDrop={this.handleDrop.bind(this)}
/>
</div>
</div>
</div>
);
}
}
这里是TaskList类:
import React from "react";
import { Draggable, Droppable } from 'react-drag-and-drop'
import update from 'immutability-helper';
export default class TaskList extends React.Component {
static getElementId(e) {
let id = null;
for (let key in e) {
if (e[key] !== '') {
id = e[key];
}
}
return id;
}
static sortByPriority(a, b) {
return b.priority - a.priority;
}
onDrop(e) {
if (!e) return;
const id = TaskList.getElementId(e);
this.props.handleDrop(id, this.props.type)
}
orderTasks() {
const tasks = this.props.data.filter((el) => {
return el.type === this.props.type;
});
// tasks.sort(TaskList.sortByPriority);
tasks.sort(function (a, b) {
return new Date(a.date) - new Date(b.date);
});
return tasks;
}
handleSubmit(e) {
e.preventDefault();
}
editTask(e) {
//var desc = e.target.value;
//
//this.setState({
// tasks: {description: desc}
//})
}
deleteTask(index) {
var state = this.props.data;
console.log(index);
state.splice(index, 1);
localStorage.setItem('tasks', JSON.stringify(state));
this.setState({
tasks: state
})
}
render() {
const tasks = this.orderTasks();
return (
<Droppable
className="list" types={this.props.allowedTypes}
onDrop={this.onDrop.bind(this)}
>
<ul>
{tasks.map((task) => {
return (
<Draggable
type={this.props.type}
key={task.id}
data={task.id}
>
<li>
<div className="card">
<b>Task description:</b><br/>
{task.type === 'do_it' ?
<form>
<input
type="text"
defaultValue={task.description}
onChange={this.editTask.bind(this)}
/>
<input
type="button"
onSubmit={this.handleSubmit.bind(this)}
value="Edit"
/>
</form>
: <p>{task.description}</p>}
<p><b>Time: </b>{task.time}</p>
<div className="priority"><b>Priority:</b> {task.priority}</div>
{task.type === 'aborted' ? <button className="close"
onClick={this.deleteTask.bind(this, task.id)}>×</button> : null}
{task.type === 'done' ? <button className="close"
onClick={this.deleteTask.bind(this, task.id)}>×</button> : null}
</div>
</li>
</Draggable>
)
})}
</ul>
</Droppable>
);
}
}
答案 0 :(得分:1)
就像通过将任务添加到您的状态来添加任务一样,您必须将状态更新为一组新的任务,这些任务不包括您尝试删除的任务,然后React将删除已删除的任务来自DOM。在你的deleteTask函数中:
this.setState( state => ({ tasks : state.tasks.filter(x => x.id !== id ) }))
只需注意:一般情况下,当您推送新项目时,您希望避免直接改变this.state,就像在addTasks中一样。而是考虑使用数组的concat函数创建一个新数组:
this.setState( state => ({ tasks: state.tasks.concat(task) }) )
或使用ES6中的spread syntax:
this.setState( state => ({ tasks: [...state.tasks, task)] }))
请注意this.setState
可以将对象作为参数或函数。当它需要一个函数时,该函数将当前状态作为参数,并且它被认为是组件的更新状态。出于性能原因,React有时不会立即更新状态,如果您只是使用对象调用this.setState
,则无法保证整个状态都是最新状态。
答案 1 :(得分:1)
由于你正在使用数组,你可以这样做以从DOM中删除任务卡:
deleteTask: function(e) {
var index = this.props.items.indexOf(e.target.value);
this.props.items.splice(index, 1);
this.forceUpdate();
}
答案 2 :(得分:0)
我通过简单的for
循环解决了我的目标:
deleteTask(id) {
const state = this.props.data;
for (var i = 0; i < state.length; i++) {
if (state[i].id === id) {
let current = state[i];
state.splice(state.indexOf(current), 1);
}
}
localStorage.setItem('tasks', JSON.stringify(state));
this.setState({
tasks: state
})
}