Next.js项目循环调用ReactDOM.render仅渲染一条评论的问题求解
问题原因
- 核心原因是
ReactDOM.render的覆盖特性:ReactDOM.render(待渲染组件, 容器节点)调用时会先清空容器内的所有已有DOM内容,再渲染新传入的组件。你在forEach循环中反复调用该方法渲染单条评论,前一次渲染的内容会被后一次覆盖,最终只会保留最后一条评论。 - 存在多处不符合React开发规范的写法:
- div元素没有原生onLoad加载事件,原代码的回调绑定逻辑本身不生效,你看到的接口调用是因为
onLoad={this.loadComments()}是同步执行方法,不是将方法作为事件回调传入。 loadComments方法没有绑定this指向,执行时内部访问this.commentListRef会报错。- 构造函数中定义的
const comments = []是局部变量,无法在实例其他方法中访问使用。
修复方案
遵循React状态驱动渲染的逻辑,不要手动操作DOM调用ReactDOM.render,修改后的完整代码如下:
import React from 'react' import axios from 'axios' import styles from './comments-list.module.css' class CommentMessage extends React.Component { render() { return (<div> <b>{this.props.username}</b> <span>: </span> <span>{this.props.message}</span> </div>) } } class CommentsList extends React.Component { constructor(props) { super(props) // 用state存储评论数据,状态更新自动触发重渲染 this.state = { comments: [] } // 绑定方法的this指向 this.loadComments = this.loadComments.bind(this) } componentDidMount() { // 组件挂载完成后加载评论,符合React生命周期规范 this.loadComments() } loadComments() { axios.get('/api/getcomments') .then(response => { // 将所有评论存入状态 this.setState({ comments: response.data }) }) .catch(err => { console.log(err) }) } render() { return (<div className={styles.commentList}> {/* 遍历评论状态批量渲染所有评论 */} {this.state.comments.map((el, idx) => ( <CommentMessage key={idx} username={el.username} message={el.message} /> ))} </div>) } } export default CommentsList
主要修复点:
- 移除了手动操作DOM渲染的逻辑,全部改用state驱动渲染,避免内容被覆盖的问题
- 调整评论加载时机到
componentDidMount生命周期,无需使用不存在的div onLoad事件 - 提前绑定方法的this指向,避免运行时报错
- 用map遍历状态批量渲染所有评论,添加key属性符合React列表渲染规范
- 将axios导入移到顶部,避免运行时重复引入
内容的提问来源于stack exchange,提问作者Captain Shane
相关产品推荐
相关产品推荐

