为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

紫衣仙女 2022-11-03 10:33:24

所以这是我正在尝试创建的用户功能: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'


查看完整描述

4 回答

?
慕村9548890

TA贡献1643条经验 获得超1个赞

您忘记了输入元素上的 onChange 处理程序来设置项目的杂项值。


Tasks.jsx 必须如下所示


import React, {useState} from 'react'


function Tasks (props) {


const [isEditing, setIsEditing] = useState(false)


const handleInputChange = (e)=>{

    // console.log( e.target.value );

    // your awesome stuffs goes here

}


    return(

        <div className = 'tasks-container'>

            {

                isEditing ? 

                <form>

                <input type = 'text' onChange={handleInputChange} defaultValue = {props.item.chore}/> 

                </form>

                : <h1 onDoubleClick ={()=> setIsEditing(true)}>{props.item.chore}</h1>

            }

        </div>

        

    )

}


export default Tasks


查看完整回答
反对 回复 2022-11-03
?
四季花海

TA贡献1556条经验 获得超5个赞

因此,首先,我鼓励您不要在input字段和divs 之间切换,而是使用可内容编辑的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> 

    )

}


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


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


查看完整回答
反对 回复 2022-11-03
?
拉丁的传说

TA贡献1521条经验 获得超8个赞

有关工作示例,请参见沙箱:


https://codesandbox.io/s/practical-lewin-sxoys?file=/src/App.js


您的 Task 组件需要一个 keyPress 处理程序来在按下 enter 时将 isEditing 设置为 false:


const handleKeyPress = (e) => {

    if (e.key === "Enter") {

      setIsEditing(false);

    }

  };

您的 updateHandler 也应该传递给输入的 onChange 属性,而不是 defaultValue,而是使用 value。它还需要重新配置以接收 onChange 事件,并且您可以使用索引映射任务以找到它们的状态:


const updateHandler = (e, index) => {

    const value = e.target.value;

    setTasks(state => [

      ...state.slice(0, index),

      { ...state[index], chore: value },

      ...state.slice(index + 1)

    ]);

  };

最后,TaskList 似乎是一个不必要的中间人,因为所有功能都在 App 和 Task 之间;您可以直接将任务渲染到具有您选择的 className 的 div 中。


查看完整回答
反对 回复 2022-11-03
?
红糖糍粑

TA贡献1572条经验 获得超5个赞

react-edit-text是我创建的一个包,它完全符合您的描述。

它在 React 中提供了一个轻量级的可编辑文本组件。

还提供现场演示。


查看完整回答
反对 回复 2022-11-03
  • 4 回答
  • 0 关注
  • 39 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信