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

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


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


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


应用程序.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;

任务.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


任务列表.jsx


import React from 'react'

import Tasks from './Tasks'


紫衣仙女
浏览 197回答 4
4回答

慕村9548890

您忘记了输入元素上的 onChange 处理程序来设置项目的杂项值。Tasks.jsx 必须如下所示import React, {useState} from 'react'function Tasks (props) {const [isEditing, setIsEditing] = useState(false)const handleInputChange = (e)=>{&nbsp; &nbsp; // console.log( e.target.value );&nbsp; &nbsp; // your awesome stuffs goes here}&nbsp; &nbsp; return(&nbsp; &nbsp; &nbsp; &nbsp; <div className = 'tasks-container'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isEditing ?&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <form>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <input type = 'text' onChange={handleInputChange} defaultValue = {props.item.chore}/>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </form>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : <h1 onDoubleClick ={()=> setIsEditing(true)}>{props.item.chore}</h1>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; )}export default Tasks

四季花海

因此,首先,我鼓励您不要在input字段和divs 之间切换,而是使用可内容编辑的div。然后你只需使用该onInput属性来调用一个setState函数,如下所示:function Tasks ({item}) {&nbsp; &nbsp; return(&nbsp; &nbsp; &nbsp; &nbsp; <div className = 'tasks-container'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div contenteditable="true" onInput={e => editTask(item.id, e.currentTarget.textContent)} >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {item.chore}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp;&nbsp; &nbsp; )}然后,在父组件中,您可以定义editTask为一个函数,该函数通过其 id 查找项目并将其替换为新内容(在原始任务数组的副本中,而不是原始数组本身。此外,您应该避免在组件之间重命名变量。( listOfTasks-> jobItems)。这增加了不必要的开销,并且您不可避免地会在某些时候混淆哪个变量连接到哪个变量。而是说,<MyComponent jobItems={jobItems} >或者如果您想允许更大的抽象<MyComponent items={jobItems} >,然后您可以将组件重用于作业以外的可列出项目。

拉丁的传说

有关工作示例,请参见沙箱:https://codesandbox.io/s/practical-lewin-sxoys?file=/src/App.js您的 Task 组件需要一个 keyPress 处理程序来在按下 enter 时将 isEditing 设置为 false:const handleKeyPress = (e) => {&nbsp; &nbsp; if (e.key === "Enter") {&nbsp; &nbsp; &nbsp; setIsEditing(false);&nbsp; &nbsp; }&nbsp; };您的 updateHandler 也应该传递给输入的 onChange 属性,而不是 defaultValue,而是使用 value。它还需要重新配置以接收 onChange 事件,并且您可以使用索引映射任务以找到它们的状态:const updateHandler = (e, index) => {&nbsp; &nbsp; const value = e.target.value;&nbsp; &nbsp; setTasks(state => [&nbsp; &nbsp; &nbsp; ...state.slice(0, index),&nbsp; &nbsp; &nbsp; { ...state[index], chore: value },&nbsp; &nbsp; &nbsp; ...state.slice(index + 1)&nbsp; &nbsp; ]);&nbsp; };最后,TaskList 似乎是一个不必要的中间人,因为所有功能都在 App 和 Task 之间;您可以直接将任务渲染到具有您选择的 className 的 div 中。

红糖糍粑

react-edit-text是我创建的一个包,它完全符合您的描述。它在 React 中提供了一个轻量级的可编辑文本组件。还提供现场演示。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript