【问题标题】:How to edit object (todo) in array? (reactjs)如何编辑数组中的对象(待办事项)? (反应)
【发布时间】:2020-08-08 09:19:13
【问题描述】:

所以我有这个待办事项列表应用程序,我正在编辑待办事项的名称。

当我点击按钮 edit 时,我在输入字段中获取名称的值,当我在该字段中输入内容并按 Enter 时,它应该更改/更新待办事项的名称,但现在它是只添加新的待办事项。

这是我目前工作的代码,我删除了所有不成功的尝试。我没有更多的想法了。

import React, { useRef, useReducer } from 'react'

function App() {

    const inputRef = useRef<HTMLInputElement | any>(null)

    const handleSubmit = (e: any) => {
        e.preventDefault()
        inputRef.current?.value !== "" && dispatch({ type: 'ADD_TODO', payload: inputRef.current?.value })
        inputRef.current && (inputRef.current.value = "")
    }

    const [todo, dispatch] = useReducer((state: any, action: any): any => {
        switch (action.type) {
            case 'ADD_TODO':
                return [...state, { id: state.length, name: action.payload, isCheck: false }]
            case 'CHECK_TODO':
                return state.filter((item: any, index: any): any => {
                    if (index === action.id) {
                        item.isCheck = !item.isCheck
                    }
                    return item
                })
            case 'DELETE_TODO':
                return state.filter((item: any, index: any) => index !== action.id)
            case 'EDIT_TODO':
                inputRef.current.focus()
                inputRef.current.value = action.payload
                return state
        }
    }, [])

    const todos = todo.map((item: any, index: number) => {
        return (
            <li key={index}>
                <input type="checkbox" checked={item.isCheck} onChange={() => dispatch({ type: "CHECK_TODO", id: index })} />
                {item.name}
                <button onClick={() => dispatch({ type: 'EDIT_TODO', id: index, payload: item.name })}>edit</button>
                <button onClick={() => dispatch({ type: "DELETE_TODO", id: index })}>x</button>
            </li>
        )
    })

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input
                    type="text"
                    placeholder='Buy milk'
                    ref={inputRef}
                />
            </form>
            <ul>{todos}</ul>
        </div>
    )
}

export default App

编辑

此外,作为选项,可以添加新按钮来提交编辑,而不是按 Enter。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    您必须跟踪您正在编辑的 id/index,以便您可以确定您是在更新还是在状态中添加值。以下代码可能会有所帮助。不过我删除了打字稿。

    function App() {
    
      const inputRef = React.useRef(null)
      const [editingIndex, setEditingIndex] = React.useState(null)
    
      const handleSubmit = (e) => {
        e.preventDefault()
        if(inputRef.current && inputRef.current.value !== ""){
          dispatch({ type: 'ADD_TODO', payload: inputRef.current.value, id: editingIndex})
        }
        inputRef.current && (inputRef.current.value = "")
      }
    
      const [todo, dispatch] = React.useReducer((state, action) => {
        switch (action.type) {
          case 'ADD_TODO':
            setEditingIndex(null)
            const tempState = [...state]
            if(action.id){
              tempState[action.id] = { ...tempState[action.id], name: action.payload }
            }
            else{
              tempState.push({ id: action.id || state.length, name: action.payload, isCheck: false })
            }
            return tempState
          case 'CHECK_TODO':
            return state.filter((item, index) => {
              if (index === action.id) {
                item.isCheck = !item.isCheck
              }
              return item
            })
          case 'DELETE_TODO':
            return state.filter((item, index) => index !== action.id)
          case 'EDIT_TODO':
            inputRef.current.focus()
            inputRef.current.value = action.payload
            return state
        }
      }, [])
    
      const todos = todo.map((item, index) => {
        return (
          <li key={index}>
            <input type="checkbox" checked={item.isCheck} onChange={() => dispatch({ type: "CHECK_TODO", id: index })} />
            {item.name}
            <button onClick={() => {setEditingIndex(index); dispatch({ type: 'EDIT_TODO', id: index, payload: item.name })}}>edit</button>
            <button onClick={() => dispatch({ type: "DELETE_TODO", id: index })}>x</button>
          </li>
        )
      })
    
      return (
        <div>
          <form onSubmit={handleSubmit}>
            <input
              type="text"
              placeholder='Buy milk'
              ref={inputRef}
            />
          </form>
          <ul>{todos}</ul>
        </div>
      )
    }
    
    ReactDOM.render(
        <App />,
      document.getElementById('root'))
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

      【解决方案2】:

      即使您在单击编辑按钮时使用待办事项名称填充输入,最后onSubmit 正在调用handleSubmit 函数,该函数调用ADD_TODO 减速器。

      您可以做的一件事是设置一个“编辑模式”标志,并更改handleSubmit 的调度方式,并使用索引创建一个新类型,如UPDATE_TODO。或者创建一个新函数并根据更新标志调用适当的函数,如下所示:

      <form onSubmit={editMode ? handleEdit : handleSubmit}>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多