You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React开发Wordle模拟器:点击按键填充所有方块问题修复

修复Wordle模拟器字母逐个填充问题

我正在开发一个基于React、Next.js和Bootstrap 5的Wordle模拟器作品集项目,需求是用户按下按键时,逐个将对应字母填充到方格中,但当前点击按钮时所有方格都会被填充同一个字符,而非逐个填充。

问题代码

键盘按钮代码

<div id="key-row" class="row">
  <div id="key-col" class="col">
    <button value="Q" onClick={() => this.handleTextChange('Q')} id="keyboard-button" type="button" class="btn btn-danger">Q</button>
  </div>
  <div id="key-col" class="col">
    <button value="W" onClick={() => this.handleTextChange('W')} id="keyboard-button" type="button" class="btn btn-danger">W</button>
  </div>
  <div id="key-col" class="col">
    <button value="E" onClick={() => this.handleTextChange('E')} id="keyboard-button" type="button" class="btn btn-danger">E</button>
  </div>
  <div id="key-col" class="col">
    <button value="R" onClick={() => this.handleTextChange('R')} id="keyboard-button" type="button" class="btn btn-danger">R</button>
  </div>
  <div id="key-col" class="col">
    <button value="T" onClick={() => this.handleTextChange('T')} id="keyboard-button" type="button" class="btn btn-danger">T</button>
  </div>
  <div id="key-col" class="col">
    <button value="Y" onClick={() => this.handleTextChange('Y')} id="keyboard-button" type="button" class="btn btn-danger">Y</button>
  </div>
  <div id="key-col" class="col">
    <button value="U" onClick={() => this.handleTextChange('U')} id="keyboard-button" type="button" class="btn btn-danger">U</button>
  </div>
  <div id="key-col" class="col">
    <button value="I" onClick={() => this.handleTextChange('I')} id="keyboard-button" type="button" class="btn btn-danger">I</button>
  </div>
  <div id="key-col" class="col">
    <button value="O" onClick={() => this.handleTextChange('O')} id="keyboard-button" type="button" class="btn btn-danger">O</button>
  </div>
  <div id="key-col" class="col">
    <button value="P" onClick={() => this.handleTextChange('P')} id="keyboard-button" type="button" class="btn btn-danger">P</button>
  </div>
</div>

按键处理与状态管理代码

export default class Gameboard extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.rowNumber = 1;
    this.colNumber = 1;
  }

  handleTextChange = (letter) => {
    switch('row' + this.rowNumber + 'col' + this.colNumber) {
      case 'row1col1':
        this.setState({row1col1: letter});
      case 'row1col2':
        this.setState({row1col2: letter});
      case 'row1col3':
        this.setState({row1col3: letter});
      case 'row1col4':
        this.setState({row1col4: letter});
      case 'row1col5':
        this.setState({row1col5: letter});
      case 'row2col1':
        this.setState({row2col1: letter});
      case 'row2col2':
        this.setState({row2col2: letter});
      case 'row2col3':
        this.setState({row2col3: letter});
      case 'row2col4':
        this.setState({row2col4: letter});
      case 'row2col5':
        this.setState({row2col5: letter});
      default:
          this.setState({'': ''});
    }
  }

方格渲染代码

render() {
    return (
        <div id="game-box" class="container">
          <div id="row" class="row">
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row1col1}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row1col2}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row1col3}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row1col4}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row1col5}</p></div>
              </div>
          </div>
          <div id="row" class="row">
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row2col1}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row2col2}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row2col3}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row2col4}</p></div>
              </div>
              <div id="col" class="col">
                <div id="box"><p id="entry">{this.state.row2col5}</p></div>
              </div>
          </div>

错误原因

  1. Switch无break导致穿透执行:每个case语句后没有添加break,当匹配到第一个case(比如row1col1)后,代码会继续执行后续所有case,把所有rowXcolY的state都设为同一个字母。
  2. 未更新行列指针:每次输入后没有修改rowNumber和colNumber,导致永远只会匹配第一个case,无法移动到下一个方格。

修复方案

1. 修正Switch逻辑,添加break(基础修复)

确保每个case执行后跳出switch,避免穿透;同时在每次输入后更新行列指针,指向下一个方格:

export default class Gameboard extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.rowNumber = 1;
    this.colNumber = 1;
    // 初始化所有方格为空
    for (let row = 1; row <= 2; row++) {
      for (let col = 1; col <=5; col++) {
        this.state[`row${row}col${col}`] = '';
      }
    }
  }

  handleTextChange = (letter) => {
    const currentCell = `row${this.rowNumber}col${this.colNumber}`;
    // 只更新当前方格的状态
    this.setState({ [currentCell]: letter }, () => {
      // 更新行列指针,确保下一次输入填充下一个方格
      if (this.colNumber < 5) {
        this.colNumber++;
      } else if (this.rowNumber < 2) { // 可根据需求修改总行数,比如Wordle的6行
        this.rowNumber++;
        this.colNumber = 1;
      }
      // 所有行填满后可添加阻止输入的逻辑
    });
  }

2. 优化State结构(推荐)

将分散的rowXcolY字段改为二维数组,代码更简洁易维护:

export default class Gameboard extends Component {
  constructor(props) {
    super(props);
    // 初始化6行5列的空棋盘(符合Wordle标准)
    this.state = {
      board: Array(6).fill().map(() => Array(5).fill('')),
      currentRow: 0,
      currentCol: 0
    };
  }

  handleTextChange = (letter) => {
    const { board, currentRow, currentCol } = this.state;
    // 复制棋盘避免直接修改state
    const newBoard = [...board];
    // 只更新当前位置的字母
    if (currentCol < 5 && currentRow < 6) {
      newBoard[currentRow][currentCol] = letter;
      this.setState({
        board: newBoard,
        // 更新当前位置:列满则换行
        currentCol: currentCol + 1 === 5 ? 0 : currentCol + 1,
        currentRow: currentCol + 1 === 5 ? currentRow + 1 : currentRow
      });
    }
  }

  render() {
    const { board } = this.state;
    return (
      <div id="game-box" class="container">
        {board.map((row, rowIndex) => (
          <div key={rowIndex} class="row">
            {row.map((letter, colIndex) => (
              <div key={colIndex} class="col">
                <div id="box"><p id="entry">{letter}</p></div>
              </div>
            ))}
          </div>
        ))}
      </div>
    );
  }
}

效果验证

修改后,点击键盘按钮时字母会依次填充到当前行的每个方格,填满一行后自动切换到下一行,不会再出现所有方格同时填充的问题。

内容的提问来源于stack exchange,提问作者Aeryes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 06:28:09