React.js ToDo应用程序中的编辑功能有什么问题?

时间:2018-09-23 13:02:59

标签: javascript

我正在使用React.js开发实习ToDo应用,并停留在便笺编辑功能上。 逻辑已基本完成,但我坚持使用“ TypeError:arr [i]未定义”来保存已编辑的注释。 我将在GitHub上发布整个项目的链接,代码很简单,主要逻辑在ToDo.js和ToDoItem.js文件中。 通常,将参数从“保存”功能发送到“ editItem”功能时遇到问题。 请帮助我,我只是React的新手... https://github.com/Wonderio619/magisale-internship-todo ToDoItem.js

import React, {Component} from 'react';
import './ToDoItem.css';

class ToDoItem extends Component {
    constructor(props) {
        super(props);
        this.state = {
            editMode: false,
        }
      };

      edit = () => {
        this.setState ({editMode: true});
      };

      save = () => {
        let updTitle = this.refs.newTitle.value;
        let updToDo = this.refs.newToDo.value;
        this.props.editItem (updTitle, updToDo, this.props.key);

        this.setState ({
          editMode: false})
      };

      renderNormal = () => {
        return (
            <div className="ToDoItem">
            <p className="ToDoItem-Text">{this.props.title}</p>
            <p className="ToDoItem-Text">{this.props.todo}</p>
            <button className="ToDoItem-Edit" onClick={this.edit}>&#x270D;</button>
            <button className="ToDoItem-Delete" onClick={this.props.deleteItem}>-</button>
        </div>
        );
      };

      renderEdit = () => {
        return (
          <div className="ToDoItem">
            <textarea ref="newTitle" defaultValue={this.props.title}></textarea>
            <textarea ref="newToDo" defaultValue={this.props.todo}></textarea>
            <button onClick={this.save} className="ToDoItem-Save">&#128190;</button>
          </div>
        );
      };

      render() {
        if (this.state.editMode) {
          return this.renderEdit ();
        } else {
          return this.renderNormal ();
        }
      }
}

export default ToDoItem;

ToDo.js

import React, {Component} from 'react';
import './ToDo.css';
import ToDoItem from './components/ToDoItem';
import Logo from './assets/logo.png';

class ToDo extends Component {
    constructor(props) {
        super(props);
        this.state = {
            list: [
                {
                    title: 'Cup cleaning',
                    todo: "Wash and take away the Kurzhiy's cup from WC"
                },
                {
                    title: 'Smoking rollton',
                    todo: 'Do some rollton and cigarettes'
                },
                {
                    title: 'Curious dream',
                    todo: 'Build a time machine'
                }
            ],
            title: '',
            todo: ''
        };
    };

    createNewToDoItem = () => {
      this.setState(({ list, title, todo }) => ({
        list: [
            ...list,
          {
            title,  
            todo
          }
        ],
        title: '',
        todo: ''
      }));
    };

    handleKeyPress = e => {
        if (e.target.value !== '') {
          if (e.key === 'Enter') {
            this.createNewToDoItem();
          }

        }
    };

    handleTitleInput = e => {
      this.setState({
        title: e.target.value,
      });
    };

    handleTodoInput = e => {
        this.setState({
         todo: e.target.value
      });
    };

    deleteItem = indexToDelete => {
        this.setState(({ list }) => ({
          list: list.filter((toDo, index) => index !== indexToDelete)
      }));
    };

    editItem = (updTitle, updToDo, i) => {
        let arr = this.state.list;
        arr[i].title = updTitle;
        arr[i].todo = updToDo;
        this.setState ({list: arr});
    };

    eachToDo = (item, i) => {
        return <ToDoItem
                    key={i}
                    title={item.title}
                    todo={item.todo}
                    deleteItem={this.deleteItem.bind(this, i)}
                    editItem={this.editItem.bind(this, i)}
                />
      };

    render() {
        return (
            <div className="ToDo">
                <img className="Logo" src={Logo} alt="React logo"/>
                <h1 className="ToDo-Header">MAGISOFT REACT INTERNSHIP TODO</h1>
                <div className="ToDo-Container">

                    <div className="ToDo-Content">
                        {this.state.list.map(this.eachToDo)}
                    </div>

                    <div>
                       <input type="text" placeholder="Enter new title" value={this.state.title} onChange={this.handleTitleInput} onKeyPress={this.handleKeyPress}/>
                       <input type="text" placeholder="Enter new todo" value={this.state.todo} onChange={this.handleTodoInput} onKeyPress={this.handleKeyPress}/>
                       <button className="ToDo-Add" onClick={this.createNewToDoItem}>+</button>
                    </div>

                </div>
            </div>
        );
    }
}

export default ToDo;

1 个答案:

答案 0 :(得分:0)

将您的编辑项目更新为以下内容,它将起作用。实际上,您正在使用this.editEditItem.bind(this,i)。由于要通过哪个索引作为第一个参数。

editItem = (i, updTitle, updToDo) => {
    let arr = this.state.list;
    arr[i].title = updTitle;
    arr[i].todo = updToDo;
    this.setState ({list: arr});
};