我想知道我的解决方案是传统的,还是有更好的,更常见的方法使用React来解决这种情况:
我有一个评论区。我从服务器检索一个注释列表,作为我的功能组件的支柱。在JSX中,我映射每个注释,并为每个注释返回一个TextArea来显示注释。其中一个功能是,如果您创建了评论,将出现一个编辑按钮,使文本区域可编辑。
这意味着我需要每个文本区域的唯一标识符,因为一旦用户编辑评论的内容并单击保存按钮,我需要在数据库中使用评论的正确_id发布到我的服务器,以及更新的内容。到目前为止,我最惯用的解决方案是使用refs,代码如下:
-
我创建了一个ref包含一个数组,一个函数传递对象映射的评论。_id添加到元素,并在调用函数时将其添加到commentRefs数组中。要添加到ref数组的函数是textarea的ref属性值:
const addCommentRef = _id => el => { if(el && !commentRefs.current.includes(el) && el) { const commentRef = { _id, el, content: '', } commentRefs.current.push(commentRef); }
}
<textarea ref={addCommentRef(comment._id)}
On the textarea onChange, I call a function called editCommentRef, which maps through the commentRefs, compares the ID's passed as param with each _id value in the array and if found, updates the content to what has been typed into the textarea:
const editCommentViaRef = _id => event => { for(let i = 0; i < commentRefs.current.length; i++) { const commentRef = commentRefs.current[i]; if(_id == commentRef._id) { commentRefs.current[i] = { ...commentRefs.current[i], content: event.target.value } } }
}
-
最后,一旦保存按钮被单击,它的onClick处理程序调用名为savecommenedit的第三个函数,它传递评论的_id。我们再次遍历commentRefs数组并找到与保存对象的_id匹配的_id参数。一旦发现,我有什么我需要张贴到服务器/db和更新评论:
const saveCommentEdit = _id =>{commentRefs.current.forEach((评论)=比;{If (_id == comment._id) {Console.log('找到要保存到数据库的注释',注释。_id + ' saving content - n' + comment.content);}}(;}
& lt;按钮onSubmit = {saveCommentEdit (comment._id)}…
这是有效的,但是这是否太复杂了?是否有更好和通用的解决方案?我尝试过/考虑过的其他解决方案:
-
States—我想我会遇到与状态相同的问题,因为状态名称需要在代码中引用,所以我需要为每个状态使用不同的变量名称。此外,状态将要求整个组件重新渲染每个字符输入到文本区域,这似乎比refs更昂贵。
-
文档选择器-最简单的解决方案是调用一个函数,该函数使用"findElementById"等. .在这种情况下,我通过使每个文本区域的ID包含comment._id来提供唯一标识符。这里明显的问题是,在React应用程序中直接针对DOM是不鼓励的,这从根本上与React框架相矛盾。
提前感谢!
你不需要使用Ref
-它意味着别的东西(与DOM
通信),你的任务是不同的。您可以在每个组件中存储数据库中的编辑状态和record id
。您可以存储author's id
以确切地知道谁可以编辑。在服务器上,更新记录,前提是id和作者相同。此外,您不需要做任何循环,注释组件可以根据OOP
自行负责发送数据。
例如,您的数据库中可能有一个表comments
: