React迭代器元素缺失key属性报react/jsx-key及函数报错如何解决
React报错问题解决方案
1. 解决react/jsx-key规则错误
- 报错原因:React遍历渲染列表时,每一个迭代生成的最外层JSX元素必须添加唯一的
key属性,用于虚拟DOM的diff性能优化,你的代码中comments.map返回的<li>元素未添加该属性。 - 修复方案:
若当前评论没有唯一ID、且列表无频繁排序/删除操作,可以直接使用数组索引作为key:
若列表有频繁更新操作,推荐在新增评论时生成唯一ID作为key,修改addComment内的setComments逻辑即可:{comments.map((c, index) => <li key={index}> {/* 原有li内的代码 */} </li> )}setComments([...comments, { id: Date.now(), // 新增唯一id字段 comment: comment, date: moment() }]) // 渲染时取id作为key <li key={c.id}>
2. 解决addComment函数报错+输入框清空问题
- 报错原因:
- 函数组件错误使用类组件的
React.createRef()创建引用,函数组件每次重渲染都会生成新的ref对象,导致commentInput.current可能为undefined,访问value时抛出异常 - 输入框同时绑定了
value={comment}受控属性和ref,属于混用受控/非受控组件的错误写法,完全不需要通过ref获取输入值
- 函数组件错误使用类组件的
- 修复方案:
- 删除
const commentInput = React.createRef();代码,同时删除input标签上的ref={commentInput}属性 - 修改addComment函数,直接使用已有的
comment状态值作为新增评论内容,不需要操作ref,setComment('')执行后,绑定了value={comment}的输入框会自动清空 - 若按钮没有包裹在form标签内,可删除无用的
e.preventDefault()代码
- 删除
修复后完整代码
import React, { useContext, useState } from 'react'; import ContentHeader from './PatientHeader'; import { PatientContext } from '../App'; const moment = require('moment'); const ContentInfo = () => { const { selectedPatient, comments, setComments } = useContext(PatientContext); const [comment, setComment] = useState(''); const addComment = (e: any) => { const date = moment(); setComments([...comments, { id: Date.now(), comment: comment, date: date }]); setComment(''); }; const handleChange = (e: any) => setComment(e.target.value); return ( <div className='content'> <ContentHeader /> <div className='info'> <div className='comments'> <div> <p> <h3 className='comments-text'>Comments:</h3> </p> <ul> {comments.map(c => <li key={c.id}> <div className='new-comment'> <div> <strong>{moment(c.date).format('ll')}</strong> </div> <div> {c.comment} </div> </div> </li> )} </ul> </div> <div className='create-commentInput'> <input value={comment} onChange={handleChange} className='form-control' type="text" /> <button onClick={addComment} className='add-btn'>+</button> </div> </div> </div> </div> ); }
内容的提问来源于stack exchange,提问作者Artemij
相关产品推荐
相关产品推荐

