无法在 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>
);
}
}
我正在构建一款战舰游戏,并在用户点击标签时向我的服务器发送请求。该点击已在我的 "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>
);
}
}