如何动态操作TaskList中的道具?

时间:2017-07-20 07:05:05

标签: reactjs

我很反应。我坚持用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)}>&times;</button> : null}
                                        {task.type === 'done' ? <button className="close"
                                                                        onClick={this.deleteTask.bind(this, task.id)}>&times;</button> : null}
                                    </div>
                                </li>
                            </Draggable>
                        )
                    })}
                </ul>
            </Droppable>
        );
    }
}

3 个答案:

答案 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
        })
    }