javascript - 如何在 React 中将输入数据添加到 JSON 数组?

标签 javascript reactjs

我一直致力于理解 React 概念并完成了我的 Todo 项目。我显示了虚拟数据,但无法向我的虚拟数据添加新值,该数据存储在单独文件 todos.js 中的对象数组中。

这是 file hierarchy


这是我得到的错误 -

index.js:2177 警告:数组或迭代器中的每个子项都应该有一个唯一的“键”属性。


待办列表.js

import React from 'react';
import Todo from './Todo';
import todos from '../todos'

class TodoList extends React.Component {
    constructor() {
        super();
        this.state = {
            todoItems: todos,
            newItem: {}
        }
    }

    addItem = (event) => {
        event.preventDefault();
        const todoList = this.state.todoItems;
        todoList.push(this.state.newItem);
        this.setState({ 
            todoList: todos,
            newItem: {}
        });

    };

    handleInput = (event) => {
        this.setState({ newItem: event.target.value });
    }

    render() {
        const itenary = this.state.todoItems;
        return (
            <div>
                {itenary.map(todo =>
                    <div key={todo.id}>
                        <Todo handleClick={this.props.handleClick} thing={todo} />
                    </div>

                )}
                <br />
                <form onSubmit={this.addItem}>
                    <input type="text" onChange={this.handleInput} placeholder="Add a new task" />
                    <button>Submit</button>
                </form>
            </div>
        );
    }
}

export default TodoList;

待办事项

import React from 'react';

class Todo extends React.Component {
    constructor() {
        super();
        this.state = {
            clicked: false
        }
    }


    handleClick = () => {
        this.setState({ clicked: !this.state.clicked });
    }

    render() {
        const styles = this.state.clicked ? { textDecoration: 'line-through' } : { textDecoration: 'none' };
        return (
            {/* This is where the todo item is*/}
            <div style={styles} onClick={this.handleClick} key={this.props.thing.id}>{this.props.thing.text}</div>
        );
    }
}

export default Todo;

待办事项.js

const todos = [
    { id: 1, text: 'Go to the gym', 'completed': false },
    { id: 2, text:  'Do laundry', 'completed': false },
    { id: 3, text: 'Study for exams', 'completed': false },
    { id: 4, text: 'Read a book', 'completed': false },
    { id: 5, text: 'Clean the bedroom', 'completed': false },
    { id: 6, text: 'Go to the park', 'completed': false },
];

export default todos; 

感谢任何帮助和/或反馈。

最佳答案

您必须为添加到 todoItems 的新待办事项提供一个唯一的 id,当您渲染它们时,React 可以使用它来区分它。

您也不应该使用 push 改变当前状态。您应该改为使用一个全新的数组来设置状态,该数组包含前一个数组所做的一切。

示例

class TodoList extends React.Component {
  constructor() {
    super();
    this.state = {
      todoItems: todos,
      newItem: ""
    };
  }

  addItem = event => {
    event.preventDefault();
    this.setState(prevState => {
      return {
        todoItems: [
          ...prevState.todoItems,
          { id: Math.random(), text: prevState.newItem, completed: false }
        ],
        newItem: ""
      };
    });
  };

  // ...
}

const todos = [
  { id: 1, text: "Go to the gym", completed: false },
  { id: 2, text: "Do laundry", completed: false },
  { id: 3, text: "Study for exams", completed: false },
  { id: 4, text: "Read a book", completed: false },
  { id: 5, text: "Clean the bedroom", completed: false },
  { id: 6, text: "Go to the park", completed: false }
];

class TodoList extends React.Component {
  constructor() {
    super();
    this.state = {
      todoItems: todos,
      newItem: ""
    };
  }

  addItem = event => {
    event.preventDefault();
    this.setState(prevState => {
      return {
        todoItems: [
          ...prevState.todoItems,
          { id: Math.random(), text: prevState.newItem, completed: false }
        ],
        newItem: ""
      };
    });
  };

  handleInput = event => {
    this.setState({ newItem: event.target.value });
  };

  render() {
    const itenary = this.state.todoItems;
    return (
      <div>
        {itenary.map(todo => (
          <div key={todo.id}>
            <Todo handleClick={this.props.handleClick} thing={todo} />
          </div>
        ))}
        <br />
        <form onSubmit={this.addItem}>
          <input
            type="text"
            onChange={this.handleInput}
            value={this.state.newItem}
            placeholder="Add a new task"
          />
          <button>Submit</button>
        </form>
      </div>
    );
  }
}

class Todo extends React.Component {
  constructor() {
    super();
    this.state = {
      clicked: false
    };
  }

  handleClick = () => {
    this.setState({ clicked: !this.state.clicked });
  };

  render() {
    const styles = this.state.clicked
      ? { textDecoration: "line-through" }
      : { textDecoration: "none" };
    return (
      <div style={styles} onClick={this.handleClick} key={this.props.thing.id}>
        {this.props.thing.text}
      </div>
    );
  }
}

ReactDOM.render(<TodoList />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

关于javascript - 如何在 React 中将输入数据添加到 JSON 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51699285/

相关文章:

javascript - 如何根据字符第三次出现来剪切字符串?

javascript - 尝试将数据从子级传递到父级时出现 setState 问题

javascript - 图像预览在 react 中不起作用

javascript - 在 react 导航中将 Prop 很好地传递到屏幕

javascript - 如何用字形替换数据切换文本? (使用 Rails 和 JS)

javascript - 如何使用 Youtube API 判断 YouTube 视频何时播放

javascript - 从另一个 JS 文件访问对象时未捕获的 ReferenceError

javascript - 单选按钮的不同值(如果选择或未选择)

reactjs - 无法在 react 中正确显示路线

javascript - 如何在 react 异步调用后测试状态更新和组件重新渲染