React实现评论盒时保存数组到state后评论列表无法正常显示问题
问题原因
- 核心错误是你往
commentArray里存的是嵌套数组而非对象:你在commentWrite中定义的comment本身是一个包了对象的数组,执行setCommentArray([...commentArray, comment])后,commentArray的每个元素都是数组类型,而非你预期的评论对象。后续执行map遍历的时候,取comment.name自然是undefined,所以页面渲染不出内容。 - 你看到控制台数组更新是个假象:React的
setState是异步更新的,你在setCommentArray后立刻打印commentArray,拿到的还是更新前的旧值,Chrome控制台打印引用类型时会展示最新值,只是让你误以为打印时已经更新了。 - 额外的小问题:输入框没有绑定
value属性,属于非受控组件,后续清空输入或者取值都会有隐患。
修复方案
- 将
commentWrite中的comment变量改为直接定义为对象,不要外层包数组 - 优先使用函数式写法更新数组state,避免闭包导致的旧值问题
- 给输入框绑定
value属性,提交后清空输入框,优化使用体验
修复后完整代码
import '../App.css'; import React, { useState } from 'react'; function App(props) { const [userName, setUserName] = useState(""); const [userComment, setUserComment] = useState(""); const [commentArray, setCommentArray] = useState([]); const commentWrite = (event) => { event.preventDefault(); // 直接定义为对象,不要包数组 const newComment = { name: userName, comment: userComment }; // 函数式更新,确保拿到最新的之前的数组 setCommentArray(prev => [...prev, newComment]); // 清空输入框 setUserName(""); setUserComment(""); }; const comments = commentArray.map((comment, index) => { return ( <tr key={index}> <td>{comment.name}</td> <td>{comment.comment}</td> </tr> ) }); return ( <> <div className="wrapper"> <header className="App-header"> <h1>Comment box</h1> </header> <div className="commentInput"> <form> <input type="text" placeholder="Name" required value={userName} onChange={e => setUserName(e.target.value)}></input> <input type="text" placeholder="Comment" required value={userComment} onChange={e => setUserComment(e.target.value)}></input> <button type="submit" onClick={commentWrite} >Post</button> </form> </div> <table> <thead> <tr> <th>Name</th> <th>Comment</th> </tr> </thead> <tbody> {comments} </tbody> </table> </div> </> ); } export default App;
内容的提问来源于stack exchange,提问作者esvnt
相关产品推荐
相关产品推荐

