【问题标题】:React: trying to automatically select newly created list itemReact:尝试自动选择新创建的列表项
【发布时间】:2020-10-14 09:02:54
【问题描述】:

我正在尝试制作一个强制性的 Todo 应用程序来帮助我学习 React,但我正在努力获得 .这是一个有多个待办事项列表可供选择的待办事项应用程序。我要的行为是一个待办事项列表的列表,您可以在其中选择一个和该节目的待办事项(如 wunderlist/msft 待办事项)。选择一个不同的列表,它的待办事项显示等。此时它使用静态 json,其中每个项目都有一个子数组。

此时我可以创建一个新的待办事项列表,手动选择它,然后将待办事项添加到该列表中。我想做的是自动选择新创建的待办事项列表,这样我就可以开始添加待办事项了。

我有一个名为 getTodoDetails 的函数,我在其中传递 id 以显示它的孩子,但在这种情况下它不起作用。任何想法如何让这个工作?谢谢!

主要工作示例:https://codesandbox.io/s/recursing-keldysh-kg9bv?file=/src/data/Todo.js

这是我的代码:

Todo.js

const TodoData = [
    {
        "Id": 1,
        "Title": "Groceries",
        "TodoList": [
            {
                "Id": 1,
                "Title": "Apples"
            },
            {
                "Id": 2,
                "Title": "Oranges"
            },
            {
                "Id": 3,
                "Title": "Bananas"
            }
        ]
    },
    {
        "Id": 2,
        "Title": "Daily Tasks",
        "TodoList": [{
            "Id": 11,
            "Title": "Clean Kitchen"
        },
        {
            "Id": 12,
            "Title": "Feed Pets"
        },
        {
            "Id": 13,
            "Title": "Do Stuff"
        }]
    },
    {
        "Id": 3,
        "Title": "Hardware Store",
        "TodoList": []
    },
    {
        "Id": 4,
        "Title": "Costco",
        "TodoList": [{
            "Id": 21,
            "Title": "Diapers"
        },
        {
            "Id": 22,
            "Title": "Cat Food"
        },
        {
            "Id": 23,
            "Title": "Apples"
        },
        {
            "Id": 24,
            "Title": "Bananas"
        }]
    },
    {
        "Id": 5,
        "Title": "Work",
        "TodoList": [
            {
                "Id": 34,
                "Title": "TPS Reports"
            }
        ]
    }
]

export default TodoData;

App.js

import React, { useEffect, useState } from 'react';
import TodoData from './data/Todo.js';

function App() {
  const [todoData, setTodoData] = useState([]);
  const [todoDetails, setTodoDetails] = useState(null);
  const [todoListToAdd, setTodoListToAdd] = useState('');
  const [todoItemToAdd, setTodoItemToAdd] = useState('');

  useEffect(() => {
    getTodoData();
  }, []);

  const getTodoData = () => {
    setTodoData(TodoData);
    getTodoDetails(TodoData[0].Id);
  };

  const getTodoDetails = id => {
    const todoList = (todoData.length === 0) ? TodoData : todoData;
    const result = todoList.find(x => x.Id === id);
    console.log(result);
    setTodoDetails(result);
  };

  const addListHandler = e => {
    e.preventDefault();
    const newItem = {
      "Id": randomNumber(),
      "Title": todoListToAdd,
      "TodoList": []
    }
    const newArray = [...todoData, newItem];
    setTodoData(newArray);
    setTodoListToAdd('');
    getTodoDetails(newItem.Id); //this is where I'm trying to 'select' the newly created todo item
    console.log(todoDetails);
  };

  const addTodoHandler = e => {
    e.preventDefault();
    const newItem = {
      "Id": randomNumber(),
      "Title": todoItemToAdd
    }
    const newArray = [...todoDetails.TodoList, newItem];
    todoDetails.TodoList = newArray;
    setTodoItemToAdd('');
  };

  const randomNumber = () => {
    return Math.floor(Math.random() * 200) + 100;
  }

  const handleDoubleClick = () => {
    console.log('double click');
  };

  const updateAddList = e => {
    setTodoListToAdd(e.target.value);
  };

  const updateAddTodo = e => {
    setTodoItemToAdd(e.target.value);
  };

  return (
    <div className="App">
      <div className="container-fluid">
        <Header />
        <div className="row">
          <div className="list-group col-sm-4 offset-sm-1">
            {todoData.map(todos => (
              <button
                key={todos.Id}
                className="list-group-item list-group-item-action d-flex justify-content-between align-items-center"
                onClick={() => getTodoDetails(todos.Id)}
                onDoubleClick={handleDoubleClick}
              >
                {todos.Title}
                <span className="badge badge-primary badge-pill">
                  {todos.TodoList.length}
                </span>
              </button>
            ))}
            <form className="form-inline my-1" onSubmit={addListHandler}>
              <input className='form-control' type="text" placeholder="Add New List" value={todoListToAdd} onChange={updateAddList} />
              <button className='btn btn-primary'>+</button>
            </form>
          </div>
          <div className="col-sm-6">
            {todoDetails && (
              <ul className="list-group">
                <h2>{todoDetails.Title} List</h2>
                {todoDetails.TodoList.map(details => (
                  <li className="list-group-item list-group-item-action" key={details.Id}>
                    {details.Title}
                  </li>
                ))}
              </ul>
            )}
            <form className="form-inline my-1" onSubmit={addTodoHandler}>
              <input className='form-control' type="text" placeholder="Add New Todo" value={todoItemToAdd} onChange={updateAddTodo} />
              <button className='btn btn-primary'>+</button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

你不需要像这样使用getTodoDetails(newItem.Id) 只需setTodoDetails(newItem)

const addListHandler = e => {
    e.preventDefault();
    const newItem = {
      Id: randomNumber(),
      Title: todoListToAdd,
      TodoList: []
    };
    const newArray = [...todoData, newItem];
    setTodoData(newArray);
    setTodoListToAdd("");
    setTodoDetails(newItem);
  };

你可以在这里查看codesandbox。希望对你有帮助

【讨论】:

  • 我像往常一样想多了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
相关资源
最近更新 更多