无法在 JSX 中重新呈现保存在 react.js 状态中的 span 标签

Unable to re-render span tags in JSX that are saved in state in react.js

我正在构建一款战舰游戏,并在用户点击标签时向我的服务器发送请求。该点击已在我的 "fire" 方法中注册,此方法向我的服务器发送 post 请求,我的服务器以 [​​=22=] "Hit" 等响应...我的问题是我我无法将我的 span 标签的值更新为 1 而不是默认值 0。这样我就可以向用户显示他们已经击中或错过了一艘船。在下面的代码片段中,我认为我的错误可能源于我最初将我的 span 标签加载到

标签下,并且这些标签没有像我认为的那样更新。如果有人对我如何获得我正在寻找的结果有一些建议,将不胜感激!

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      boardData: [],
      test: 0
    }
  }

  fire(e) {
    var boardLetter;
    var boardNumber = e.charAt(1);
    if(e.charAt(0) === "A") {
      boardLetter = 0;
    } else if(e.charAt(0) === "B") {
      boardLetter = 1;
    } else if(e.charAt(0) === "C") {
      boardLetter = 2;
    } else if(e.charAt(0) === "D") {
      boardLetter = 3;
    } else if(e.charAt(0) === "E") {
      boardLetter = 4;
    } else if(e.charAt(0) === "F") {
      boardLetter = 5;
    } else if(e.charAt(0) === "G") {
      boardLetter = 6;
    } else if(e.charAt(0) === "H") {
      boardLetter = 7;
    } else if(e.charAt(0) === "I") {
      boardLetter = 8;
    } else if(e.charAt(0) === "J") {
      boardLetter = 9;
    }
    axios.post('http://localhost:8080/fire', {
      boardPiece: e
    })
    .then(data => {
      console.log('data ', data.data, this.state.test);
      // this.state.boardData[0][1].props.children = 1
      this.setState({test: 1});
    })
    .catch(err => {
      console.log('err ', err);
    })
  }

  componentWillMount() {
    var count = 0;
    for(var i = 0; i < 10; i++) {
      var letters = ["A","B","C","D","E","F","G","H","I","J"];
      var row = [];
      for(var j = 1; j < 11; j++) {
      row.push(<span className={letters[count] + j} key={letters[count] + j} onClick={this.fire.bind(this, letters[count] + j)}>{this.state.test}</span>);
      }
      this.state.boardData.push(row);
      count++;
    }
  }

  componentDidMount() {
    axios.get('http://localhost:8080/')
    .then(function(response) {
      console.log('response: ', response.data);
    })
    .catch(function(err) {
      console.log('response error ', err);
    })
  }

  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to Battleship</h2>
        </div>
        <div className="board">
          <p> 1 2 3 4 5 6 7 8 9 10 </p>
          <p>A {this.state.boardData[0]}</p>
          <p>B {this.state.boardData[1]}</p>
          <p>C {this.state.boardData[2]}</p>
          <p>D {this.state.boardData[3]}</p>
          <p>E {this.state.boardData[4]}</p>
          <p>F {this.state.boardData[5]}</p>
          <p>G {this.state.boardData[6]}</p>
          <p>H {this.state.boardData[7]}</p>
          <p>I {this.state.boardData[8]}</p>
          <p>J {this.state.boardData[9]}</p>
        </div>
      </div>
    );
  }
}

export default App;

问题是您在 componentWillMount 期间创建的组件仅在组件第一次安装时呈现。因此,您需要将该代码移动到渲染方法或使用 componentWillReceiveProps 方法。

仅将基本数据存储在状态中,并将其他所有内容移至 render。以下不包含您的所有代码,但它 (1) 在构造函数中初始化棋盘数据 (2) 生成棋盘,包括字母,仅在 render:

var letters = ["A","B","C","D","E","F","G","H","I","J"];

class App extends Component {

  constructor() {
    super(props);

    // Construct default board data, which is a 2d-matrix
    // (an Array<Array<string>>) of either '-' for nothing, '0' for miss or '1'
    // for hit.
    var boardData = [];
    var count = 0;
    for(var i = 0; i < 10; i++) {
      var row = [];
      for(var j = 1; j < 11; j++) {
        row.push('-');
      }
      boardData.push(row);
      count++;
    }

    this.state = {
      boardData: [],
      test: 0
    }
  }

  fire(x, y) {
    axios.post('http://localhost:8080/fire', {
      boardPiece: letters[y] + x
    })
    .then(data => {
      console.log('data ', data.data, this.state.test);
      this.state.boardData[x][y] = data.data;
      this.forceUpdate();
    })
    .catch(err => {
      console.log('err ', err);
    })
  }

  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to Battleship</h2>
        </div>
        <div className="board">
          <p> 1 2 3 4 5 6 7 8 9 10 </p>
          {this.state.boardData.map((values, y) =>
            <p key={y}>
              {letters[y]}{values.map((value, x) => 
                <span>
                  {' '}
                  <span className={letters[y]} key={x} onClick={this.fire.bind(this, x, y)}>
                    {value}
                  </span>
                </span>
              )}
            </p>
          )}
        </div>
      </div>
    );
  }
}