不起作用的主要原因是按“删除”按钮不会删除项目,而按“删除”按钮不会删除项目?

时间:2020-04-07 19:13:15

标签: javascript reactjs react-hooks

我正在尝试在reacthook中创建待办事项列表。我的App.js:

import React,{useState} from 'react';
import AddTodo from './TodoFiles/AddTodo'
import TodoList from './TodoFiles/TodoList'

const defaultItems=[
  {id:1,title:'Write React Todo Project',completed:true},
  {id:2,title:'Upload it to github', completed:false}
]
const App=()=>{
  const [items,setItems]=useState(defaultItems)
  return(
    <div style={{width:400}}>
      <AddTodo items={items} setItems={setItems}/>
      <br/>
      <hr/>
      <TodoList items={items}/>
      <hr/>

    </div>
  )

}
export default App;

addTodo.js是:

import React,{useState} from 'react'

const AddTodo=({items,setItems})=>{
    const[title,setTitle]=useState('')
    const handleTitle=(event)=>{
        setTitle(event.target.value)
    }
    const handleAddTodo=()=>{
        const NewItem={title}
        setItems([NewItem,...items])
    }
    return(
        <form onSubmit={e=>{e.preventDefault();handleAddTodo()}}>
            <input type="text" placeholder="enter new task..." style={{width:350,height:15}} 
     value={title} onChange={handleTitle}/>
            <input type="submit" style={{float:'right', marginTop:2}}/>
        </form>
    )
}

export default AddTodo

TodoList.js是:

import React, { useState } from "react";

const TodoItem = ({ title, completed, completeTodo, removeTodo, index }) => {
  return (
    <div style={{ width: 400, height: 25 }}>
      <input type="checkbox" checked={completed} />
      {title}
      <button style={{ float: "right" }} onClick={() => completeTodo(index)}>
        Complete
      </button>
      <button style={{ float: "right" }} onClick={removeTodo}>
        Remove
      </button>
    </div>
  );
};
const TodoList = ({ items = [], index }) => {
  const [, setItems] = useState("");
  const completeTodo = index => {
    console.log(index);
    const newItem = [...items];
    newItem[index].completed = true;
    setItems(newItem);
  };
  const removeTodo = index => {
    setItems(items.filter((p,index)=>p.index!==index))
  };

  return items.map((p, index) => (
    <TodoItem
      {...p}
      key={p.id}
      index={index}
      completeTodo={completeTodo}
      removeTodo={removeTodo}
    />
  ));
};

export default TodoList;

CompeleteTodo已解决,但当我按删除按钮时,它不起作用,并且没有删除任何内容。执行npm start时没有错误。开发人员工具显示警告:

index.js:1 Warning: Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.
    in input (at TodoList.js:6)
    in div (at TodoList.js:5)
    in TodoItem (at TodoList.js:30)
    in TodoList (at App.js:18)
    in div (at App.js:13)
    in App (at src/index.js:9)
    in StrictMode (at src/index.js:8)

我还能修复什么?

2 个答案:

答案 0 :(得分:4)

您无需在函数的参数中设置索引,只需执行以下操作即可:

const TodoItem = ({ title, completed, completeTodo, removeTodo, index }) => {
  return (
    <div style={{ width: 400, height: 25 }}>
      <input type="checkbox" checked={completed} />
      {title}
      <button style={{ float: "right" }} onClick={() => completeTodo(index)}>
        Remove
      </button>
      <button style={{ float: "right" }} onClick={removeTodo}>
        Complete
      </button>
    </div>
  );
};
const TodoList = ({ items = [], index }) => {
  const [, setItems] = useState("");
  const completeTodo = index => {
    console.log(index);
    const newItem = [...items];
    newItem[index].completed = true;
    setItems(newItem);
  };
  const removeTodo = index => {
    const newItem = [...items];
    newItem.splice(index, 1);
    setItems(newItem);
  };

  return items.map((p, index) => (
    <TodoItem
      {...p}
      key={p.id}
      index={index}
      completeTodo={completeTodo}
      removeTodo={removeTodo}
    />
  ));
};

export default TodoList;

并且您的删除和完成功能是颠倒的:)

Check this

答案 1 :(得分:1)

这是我的建议>使用数组项ID而不是元素索引来实现remove-complete功能。


请阅读此Lists and Keys


这里是Demo

应用

import React, { useState } from "react";
import AddTodo from "./TodoFiles/AddTodo";
import TodoList from "./TodoFiles/TodoList";

const defaultItems = [
  { id: 1, title: "Write React Todo Project", completed: true },
  { id: 2, title: "Upload it to github", completed: false }
];
const App = () => {
  const [items, setItems] = useState(defaultItems);
  return (
    <div style={{ width: 400 }}>
      <AddTodo items={items} setItems={setItems} />
      <br />
      <hr />
      <TodoList items={items} setItems={setItems} />
      <hr />
    </div>
  );
};
export default App;

AddTodo

import React, { useState } from "react";

const AddTodo = ({ items, setItems }) => {
  const [title, setTitle] = useState("");
  const handleTitle = event => {
    setTitle(event.target.value);
  };
  const handleAddTodo = () => {
    const newItem = [
      {
        id: Math.max(...items.map(x => x.id), 0) + 1
        completed: false,
        title
      },
      ...items
    ];
    setItems(newItem);
  };
  return (
    <form
      onSubmit={e => {
        e.preventDefault();
        handleAddTodo();
      }}
    >
      <input
        type="text"
        placeholder="enter new task..."
        style={{ width: 350, height: 15 }}
        value={title}
        onChange={handleTitle}
      />
      <input type="submit" style={{ float: "right", marginTop: 2 }} />
    </form>
  );
};

export default AddTodo;

TodoList

import React from "react";
import TodoItem from "./TodoItem";

const TodoList = ({ items, setItems }) => {
  const completeTodo = id => {
    setItems(
      items.map(item => (item.id === id ? { ...item, completed: true } : item))
    );
  };
  const removeTodo = id => {
    setItems(items.filter(p => p.id !== id));
  };

  return items.map(p => (
    <TodoItem
      {...p}
      key={p.id}
      completeTodo={completeTodo}
      removeTodo={removeTodo}
    />
  ));
};

export default TodoList;

TodoItem

import React from "react";

const TodoItem = ({ id, title, completed, completeTodo, removeTodo }) => {
  return (
    <div style={{ width: 400, height: 25 }}>
      <input type="checkbox" checked={completed} onChange={() => {}} />
      {title}
      <button style={{ float: "right" }} onClick={() => completeTodo(id)}>
        Complete
      </button>
      <button style={{ float: "right" }} onClick={() => removeTodo(id)}>
        Remove
      </button>
    </div>
  );
};

export default TodoItem;