使用React构建待办事项列表,但它有意想不到的结果

时间:2017-02-21 13:09:36

标签: reactjs

这是我的练习演示,它是关于待办事项列表 当我确认任务时,你可以看到。它将会消失,但检查下一个任务状态。

我该如何解决?提前致谢。

enter image description here

代码:

import React, { Component } from 'react';

import InpuText from './component/InpuText';

class Note extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputdata: 'no data',
      noteData: ''
    }
  }
  componentWillMount() {
    if(localStorage.getItem('note')) {
      this.setState({
        noteData: JSON.parse(localStorage.getItem('note')).details
      })
    }
  }
  getInputValue(getValue) {
    this.setState({
      inputdata: getValue
    })
    if(localStorage.getItem('note')) {
      this.state.noteData.push({
        text: getValue
      })
      let note = {
        details: this.state.noteData
      }
      localStorage.setItem('note', JSON.stringify(note));
    }else {
      let note = {
        details: []
      }
      note.details.push({
        text: getValue
      })
      this.setState({
        noteData: note.details
      })
      localStorage.setItem('note', JSON.stringify(note));
    }
  }
  finish(index, e) {
    console.log(e.target.checked)
    if(e.target.checked === true) {
      this.state.noteData.splice(index, 1)
      this.setState({
        noteData: this.state.noteData
      })
      let note = {
        details: this.state.noteData
      }
      localStorage.setItem('note', JSON.stringify(note));
    }
  }
  render() {
    return (
      <div>
        notepad
        <InpuText getInputValue={this.getInputValue.bind(this)}/>
        {/* <p>input data:{this.state.inputdata}</p> */}
        <div>todo</div>
        {
          this.state.noteData
          ?
            <ul>
              {this.state.noteData.map((notes, i)=>(
                <li key={i}>
                  {i}:{notes.text}
                  <input type="checkbox" onChange={this.finish.bind(this, i)}/>
                </li>
              ))}
            </ul>
          :
            <p>no task</p>
        }
        <div>done</div>
        <ul>
          <li>123</li>
        </ul>
      </div>
    );
  }
}

export default Note;

finish()是句柄数组,用于删除完成任务。

1 个答案:

答案 0 :(得分:0)

我认为这是由于以下几点:

  • 您使用项目的索引(i)作为反应键。这是不好的做法,因为密钥不稳定。举个例子,考虑你有三个项目 - 它们的密钥是0,1,2。然后将中间一个标记为已完成,仅使用键0和1呈现两个项目。但是,这些项目在最后一次渲染期间分别具有键0和2,这通常意味着对齐将被搞砸。有关详细信息,请参阅https://facebook.github.io/react/docs/reconciliation.html。简而言之,渲染之间的键需要保持不变。
  • 您没有为复选框指定任何值,因此它不受控制(https://facebook.github.io/react/docs/uncontrolled-components.html),这意味着在您点击它时可以自由选中/取消选中它。

这两点一起导致你看到的行为:你点击该项,它被检查(因为输入是不受控制的),然后在下面的渲染中它与错误的项目协调(因为基于索引键)。

要解决此问题,请不要将集合索引用作键,使用实际项目中的一些不可变唯一ID(如果没有ID,请添加一个)。此外,设置复选框值prop而不是让它们不受控制。你可以,例如将isComplete属性添加到模型中的每个项目,并将复选框值prop设置为它。