Next.js中使用useEffect操作document创建游戏方块无效求助
问题原因及修复方案
核心问题
- 组件名不符合React规范:你的组件名是小写的
game,React要求组件名必须大写开头,否则会被识别为原生HTML标签,导致组件内部的所有逻辑(包括useEffect)都不会执行——这是useEffect没生成block的根本原因。 - 动态创建的block无背景色:就算
useEffect执行了,手动创建的div没有设置backgroundColor,会和背景融为一体,肉眼根本看不到。 - DOM操作不符合React理念:直接用
document.createElement和appendChild操作DOM,违背了React「状态驱动视图」的核心逻辑,组件重新渲染时手动添加的DOM元素很容易被React覆盖。
修复后的代码
import React from 'react' import { useState } from 'react'; // 组件名改为大写开头的Game function Game() { const blockWidth = 100 const blockHeight = 20 class Block { constructor(xAxis, yAxis) { this.bottomLeft = [xAxis, yAxis] this.bottomRight = [xAxis + blockWidth, yAxis] this.topLeft = [xAxis, yAxis + blockHeight] this.topRight = [xAxis + blockWidth, yAxis + blockHeight] } } // 用useState管理blocks状态,通过JSX渲染视图 const [blocks] = useState([ new Block(10, 270) ]) return ( <div className='grid' style={{ width: "600px", height: "300px", border: "solid white 1px", position: "absolute" }}> {/* 手动测试的block */} <div className='block' style={{ width: "100px", height: "20px", backgroundColor: "blue", position: "absolute", left: "50px", bottom: "50px" }}></div> {/* 遍历blocks状态渲染动态block */} {blocks.map((block, index) => ( <div key={index} className='block' style={{ width: `${blockWidth}px`, height: `${blockHeight}px`, backgroundColor: "blue", position: "absolute", left: `${block.bottomLeft[0]}px`, bottom: `${block.bottomLeft[1]}px` }} ></div> ))} </div> ) } export default Game
修复说明
- 把组件名改成
Game,符合React组件命名规范,确保组件能正常渲染。 - 用
useState管理blocks数组,通过JSX遍历渲染每个block,完全遵循React的状态驱动模式,避免手动DOM操作的问题。 - 给动态渲染的block加上
backgroundColor: "blue",确保能在页面上看到。
内容的提问来源于stack exchange,提问作者Alireza
相关产品推荐
相关产品推荐

