【问题标题】:What is the best way to update item in React Redux在 React Redux 中更新项目的最佳方法是什么
【发布时间】:2021-09-03 10:37:55
【问题描述】:

我正在学习 React Redux 并且正在编写待办事项列表应用程序。最后缺少的部分是编辑所选项目的选项(onClick)。我这样做有问题。

您能告诉我如何实现吗?

我正在寻找这样的解决方案:

  1. 选择要更新的项目(通过单击编辑图标)
  2. 表单应更改为“编辑模式”,以便用户可以将新值传递给编辑项。
  3. 传递值后,用户点击提交按钮。

我不知道如何制作编辑模式,以便我的输入表单可以处理更新现有项目。

 // ACTION
    export const editTask = (task) => ({
      type: "EDIT_TASK",
      payload: task,
    });

     // REDUCER
        const INITIAL_STATE = {
          tasks: [],
          alert: {
            show: false,
            message: "",
            type: "",
          },
          isEditing: false,
        };
        
        const reducer = (state, action) => {
          switch (action.type) {
            case "EDIT_TASK":
              return {
                ...state,
                isEditing: true,
// take current tasks and updatedTask
                tasks: [...state.tasks, action.payload],
                alert: setAlert(true, "Task has changed succesfull ????", "success"),
              };
           default:
        return state;


On my todo.jsx

    const TasksTodo = () => {
      const [inputValue, setInputValue] = useState("");
      const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
    
      const editTaskFromList = (item) => {
// match tasks from list with that selected
        const taskToEdit = state.tasks.find(
          (taskToFind) => taskToFind.id === item.id
        );
        const editedTask = {
          taskToEdit,
          title: inputValue,
        };
        dispatch(editTask([...state.tasks, editedTask]));
      };


 

     const handleSubmit = (e) => {
        e.preventDefault();
        if (inputValue) {
          const newItem = {
            id: new Date().getTime().toString(),
            title: inputValue,
          };
          dispatch(addNewTask(newItem));
          setInputValue("");
        } else {
          dispatch({ type: "NO_VALUE" });
        }
      };
    
      const handleChange = (e) => {
        setInputValue(e.target.value);
      };


  

    return (
        <div className="tasks-list-section">
          <h3 className="tasks__title">tasks List </h3>
          {state.alert.show && (
            <Alert
              {...state.alert}
              removeAlert={() => dispatch(changeAlertState())}
            />
          )}
          <form onSubmit={handleSubmit} className="tasks__form">
            <input
              type="text"
              value={inputValue}
              placeholder="e.g homework"
              className="tasks__input"
              onChange={handleChange}
            />
            <button type="submit" className="tasks__submit-btn">
              {state.isEditing ? "edit" : "submit"}
            </button>
          </form>
          {state.tasks.length > 0 && (
            <div className="tasks__container">
              <Tasks
                listItems={state.tasks}
                removeTask={removeTaskFromList}
                editTask={editTaskFromList}
              />
            </div>
          )}
        </div>
      );
    };
        

   

TaskList Component:

    const Tasks = ({ listItems, editTask, removeTask }) => {
      return (
        <div className="tasks-list">
          {listItems.map((item) => {
            const { id, title } = item;
            return (
              <div key={id} className="tasks__item">
                <p className="tasks__item--title">{title}</p>
                <div className="tasks__button-group">
                  <button
                    type="button"
                    className="tasks__button-group--edit"
                    onClick={() => editTask(item)}
                  >
                    <RiEditBoxLine className="size" />
                  </button>
                  <button
                    type="button"
                    className="tasks__button-group--delete"
                    onClick={() => removeTask(item)}
                  >
                    <RiDeleteBin6Line className="size" />
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      );
    };

【问题讨论】:

    标签: reactjs react-redux


    【解决方案1】:

    请为此找到简单的解决方法。

    Page.js(主组件)

    import React, { useState } from "react";
    import { useDispatch, useSelector } from "react-redux";
    
    import { addTask, editTask, removeTask } from "./actions";
    
    const TaskList = ({ tasks, removeTask, editTask }) => {
      return (
        <div>
          {tasks.map((item) => (
            <div key={item.id}>
              <p>{item.title}</p>
              <button type="button" onClick={(e) => editTask(item)}>
                Edit
              </button>
              <button type="button" onClick={(e) => removeTask(item)}>
                Remove
              </button>
            </div>
          ))}
        </div>
      );
    };
    
    function Page() {
      const tasks = useSelector((state) => state.tasks);
      const dispatch = useDispatch();
      const [inputValue, setInputValue] = useState("");
      const [editingTaskIndex, setEditingTaskIndex] = useState(null);
    
      const editTaskFromList = (task) => {
        const taskToEdit = tasks.find((item) => item.id === task.id);
        const taskIndex = tasks.indexOf(taskToEdit);
        setEditingTaskIndex(taskIndex);
        setInputValue(taskToEdit.title);
      };
    
      const removeTaskFromList = (task) => {
        const taskToDelete = tasks.find((item) => item.id === task.id);
        const taskIndex = tasks.indexOf(taskToDelete);
        dispatch(removeTask(taskIndex));
      };
    
      const handleSubmit = (e) => {
        e.preventDefault();
        if (editingTaskIndex === null) {
          const newItem = {
            id: new Date().getTime().toString(),
            title: inputValue
          };
          dispatch(addTask(newItem));
        } else {
          const editingItem = tasks[editingTaskIndex];
          editingItem.title = inputValue;
          dispatch(editTask(editingTaskIndex, editingItem));
        }
        setInputValue("");
        setEditingTaskIndex(null);
      };
    
      const handleChange = (e) => {
        setInputValue(e.target.value);
      };
    
      return (
        <div>
          <h3>Task List</h3>
          <form onSubmit={handleSubmit}>
            <input
              type="text"
              value={inputValue}
              placeholder="e.g: homework"
              onChange={handleChange}
            />
            <button>Submit</button>
          </form>
    
          <TaskList
            tasks={tasks}
            editTask={editTaskFromList}
            removeTask={removeTaskFromList}
          />
        </div>
      );
    }
    
    export default Page;
    

    reducer.js

    const initialState = {
      tasks: [],
      isEditing: false
    };
    
    function taskReducer(state = initialState, action) {
      switch (action.type) {
        case "ADD_TASK":
          return { ...state, tasks: [...state.tasks, action.payload] };
        case "EDIT_TASK":
          console.log(action.payload);
          const currentTasks = Array.from(state.tasks);
          currentTasks[action.payload.taskIndex] = action.payload.task;
          return { ...state, tasks: currentTasks };
        case "REMOVE_TASK":
          const allTasks = Array.from(state.tasks);
          allTasks.splice(action.payload, 1);
          return {
            ...state,
            tasks: allTasks
          };
        default:
          return state;
      }
    }
    
    export default taskReducer;
    

    Checkout the sandbox link

    【讨论】:

    • 请不要发布仅链接的答案。答案,就像问题一样,应该是具体的和完整的。 支持链接很好。
    • 感谢您的宝贵时间,但这个解决方案对我来说并不简单。你的代码对我来说看起来很复杂。
    • 在您的沙箱中,在 actionTypes.js 中,名称错误 _DIK_TASK, ADA_TASK 将它们改回 EDIT 和 ADD 并且您的沙箱可以正常工作
    • @I3artosz 在这个答案中你觉得哪个部分难以理解?
    • @PhaniRithvij 这对我来说最困难的是Reducer 中的代码“EDIT_TASK”。如果我可以通过他的 id 找到元素,我不确定这是否是使用 indexOf 数组的好方法。另一方面,我找到了不同的解决方案,我认为它更有效。我会在几分钟后发布。
    【解决方案2】:

    我找到了不同的解决方案。如果可以,请评价我的代码。

    在我的减速机上

     case "EDIT_TASK":
          return {
            ...state,
            isEditing: true,
            tasks: [
              ...state.tasks.filter((task) => task.id !== action.payload.id),
              action.payload,
            ],
            alert: setAlert(true, "Task has changed succesfull ?", "success"),
          };
    

    tasks.jsx

    const editTaskFromList = (item) => {
        const taskToEdit = state.tasks.find(
          (taskToFind) => taskToFind.id === item.id
        );
        setEditingTaskID(taskToEdit.id);
        setInputValue(taskToEdit.title);
      };
    
      const handleSubmit = (e) => {
        e.preventDefault();
    
        if (editingTaskID === null) {
          if (inputValue) {
            const newItem = {
              id: new Date().getTime().toString(),
              title: inputValue,
            };
            dispatch(addNewTask(newItem));
            setInputValue("");
          } else {
            alert("Value cannot be empty!");
          }
        } else {
          const editingItem = state.tasks.find((task) => task.id === editingTaskID);
    
          const newItem = { ...editingItem, title: inputValue };
    
          dispatch(editTask(newItem));
          setInputValue("");
          setEditingTaskID(null);
        }
      };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多