如何在 React 组件中添加编辑文本的功能?

Jos*_*mon 5 javascript reactjs

所以这是我试图创建的用户功能:1.)用户双击文本2.)文本变成输入字段,用户可以在其中编辑文本3.)用户点击回车键,提交后,文本将被更新以进行编辑文本。基本上,它只是一个编辑功能,用户可以在其中更改某些文本块。

所以这是我的问题 - 我可以通过双击将文本转换为输入字段,但是如何提交和渲染编辑后的文本?

我的父组件 App.js 存储了更新 App 状态的函数 (updateHandler)。更新的信息需要从 Tasks.jsx 组件传递,该组件是处理文本输入的地方。我还应该指出,一些道具正在通过 TaskList 发送到任务。代码如下:

应用程序.js

import React, {useState} from 'react';
import Header from './Header'
import Card from './Card'
import cardData from './cardData'
import Dates from './Dates'
import Tasks from './Tasks'
import Footer from './Footer'
import TaskList from './TaskList'

const jobItems= [
  {
      id:8,
      chore: 'wash dishes'
  },
  {
      id:9,
      chore: 'do laundry'
  },
  {
      id:10,
      chore: 'clean bathroom'
  }

]

function App() {

  const [listOfTasks, setTasks] = useState(jobItems)

  const updateHandler = (task) => {
    setTasks(listOfTasks.map(item => {
      if(item.id === task.id) {
        return {
          ...item,
          chore: task.chore
        }
      } else {
        return task
      }
    }))
  }

const cardComponents = cardData.map(card => {
  return <Card key = {card.id} name = {card.name}/>
})

return (
  <div>
    <Header/>
    <Dates/>
    <div className = 'card-container'>
    {cardComponents}
    </div>
    <TaskList jobItems = {listOfTasks} setTasks = {setTasks} updateHandler = {updateHandler}/>
    <div>
      <Footer/>
    </div>
</div>
)
}

export default App;
Run Code Online (Sandbox Code Playgroud)

任务.jsx

import React, {useState} from 'react'

function Tasks (props) {

const [isEditing, setIsEditing] = useState(false)



    return(
        <div className = 'tasks-container'>
            {
                isEditing ? 
                <form>
                <input type = 'text' defaultValue = {props.item.chore}/> 
                </form>
                : <h1 onDoubleClick ={()=> setIsEditing(true)}>{props.item.chore}</h1>
            }
        </div>
        
    )
}

export default Tasks

Run Code Online (Sandbox Code Playgroud)

任务列表.jsx

import React from 'react'
import Tasks from './Tasks'



function TaskList (props) {

    const settingTasks = props.setTasks //might need 'this'

    return (
        <div>
            {
                props.jobItems.map(item => {
                    return <Tasks key = {item.id} item = {item} setTasks = {settingTasks} jobItems ={props.jobItems} updateHandler = {props.updateHandler}/>
                })
            }
        </div>
    )
}

export default TaskList
Run Code Online (Sandbox Code Playgroud)

M-N*_*M-N 3

因此,首先,我鼓励您不要在inputfields 和divs 之间切换,而是使用contenteditable div。然后你只需使用该onInput属性来调用setState函数,如下所示:

function Tasks ({item}) {
    return(
        <div className = 'tasks-container'>
            <div contenteditable="true" onInput={e => editTask(item.id, e.currentTarget.textContent)} >
                {item.chore}
            </div>
        </div> 
    )
}

Run Code Online (Sandbox Code Playgroud)

然后,在父组件中,您可以定义editTask一个函数,通过其 id 查找项目并将其替换为新内容(在原始任务数组的副本中,而不是原始数组本身)。

此外,您应该避免在组件之间重命名变量。( listOfTasks-> jobItems)。这会增加不必要的开销,并且在某些时候您将不可避免地感到困惑哪个变量连接到哪个变量。相反,<MyComponent jobItems={jobItems} >或者如果您想要允许更大的抽象<MyComponent items={jobItems} >,那么您可以将组件重用于可列出的项目而不是作业。