React路径寻踪应用问题:仅改点击单元格类及实现拖拽绘墙
解决路径寻踪应用的墙体绘制问题
嘿,我来帮你搞定这个问题!你现在遇到的核心问题是用了一个全局的wall状态来控制所有单元格的样式,所以一点击所有单元格都变成墙了。咱们分两步来解决:先修复单个点击单元格变墙的问题,再实现拖拽连续绘制墙体的功能。
第一步:修复单个单元格点击切换墙体状态
首先,我们需要把状态从全局的wall布尔值,改成存储每个单元格是否为墙的结构。这里用一个对象walls来记录,键是行号-列号的字符串,值是布尔值表示是否是墙。
修改你的Grid.js代码如下:
import React, { Component } from "react"; export class Grid extends Component { constructor(props) { super(props); this.state = { walls: {}, // 存储每个单元格的墙体状态,格式:`${row}-${col}: boolean` isDragging: false, // 标记是否处于拖拽绘制状态 }; // 绑定事件方法,避免this指向问题 this.toggleWall = this.toggleWall.bind(this); this.handleMouseDown = this.handleMouseDown.bind(this); this.handleMouseEnter = this.handleMouseEnter.bind(this); this.handleMouseUp = this.handleMouseUp.bind(this); } componentDidMount() { // 监听全局mouseup事件,防止拖拽移出网格后无法停止绘制 document.addEventListener("mouseup", this.handleMouseUp); } componentWillUnmount() { // 组件卸载时移除全局事件监听 document.removeEventListener("mouseup", this.handleMouseUp); } // 切换指定单元格的墙体状态 toggleWall(row, col) { const cellKey = `${row}-${col}`; this.setState(prevState => ({ walls: { ...prevState.walls, [cellKey]: !prevState.walls[cellKey] } })); } // 鼠标按下时,开启拖拽状态并切换当前单元格 handleMouseDown(row, col) { this.setState({ isDragging: true }); this.toggleWall(row, col); } // 鼠标进入单元格时,如果处于拖拽状态,切换墙体 handleMouseEnter(row, col) { if (this.state.isDragging) { this.toggleWall(row, col); } } // 鼠标松开时,关闭拖拽状态 handleMouseUp() { this.setState({ isDragging: false }); } render() { let rows = []; // 注意:把列的生成放到行循环里,确保每个行的列对应正确的行号 for (let row = 0; row < 25; row++) { let columns = []; for (let col = 0; col < 60; col++) { const cellKey = `${row}-${col}`; const isWall = this.state.walls[cellKey]; columns.push( <td className={isWall ? "wall" : "grid"} onClick={() => this.toggleWall(row, col)} onMouseDown={() => this.handleMouseDown(row, col)} onMouseEnter={() => this.handleMouseEnter(row, col)} id={cellKey} key={cellKey} ></td> ); } rows.push( <tr id={row.toString()} key={row.toString()}> {columns} </tr> ); } return ( <div> <table className="grid"> <tbody>{rows}</tbody> </table> </div> ); } } export default Grid;
关键修改点说明:
- 状态结构调整:用
walls对象替代全局wall,每个单元格的状态独立存储,避免一键全改的问题 - 事件绑定:给每个单元格添加
onMouseDown、onMouseEnter事件,配合全局mouseup实现拖拽绘制的完整逻辑 - 循环逻辑优化:把列的生成放到行循环内部,确保每个单元格能正确对应自己的
row和col索引 - 状态更新:使用函数式
setState来确保状态更新的正确性,避免异步更新导致的逻辑错误
第二步:验证功能
现在你可以测试两个核心功能:
- 单个点击任意单元格,只会切换该单元格的墙体状态,不会影响其他单元格
- 按住鼠标左键拖拽,经过的单元格会连续变成墙体(再次拖拽同一区域可以取消墙体)
你的App.js和CSS代码不需要修改,保持原样即可。
内容的提问来源于stack exchange,提问作者RandyBeans
相关产品推荐
相关产品推荐

