我在学习反应,我制作了这个国家的猜谜游戏。你对此有什么改进/建议?
import React, {Component} from 'react';
import './Country.css';
class Country extends Component {
constructor(props) {
super(props);
this.state = {
countries: [],
randomCountry: {},
randomOptions: [],
userIsWin: '',
disableFieldset: false,
goodGuess: 0,
bgColor: {backgroundColor: 'white'}
}
this.getRandomCountry = this.getRandomCountry.bind(this);
this.checkWin = this.checkWin.bind(this);
}
componentDidMount() {
const apiUrl = "https://restcountries.eu/rest/v2/all";
fetch(apiUrl)
.then(data => data.json())
.then(countries => this.setState({countries}))
.then(this.getRandomCountry)
}
getRandomCountry() {
const random = this.state.countries[Math.floor(Math.random()*this.state.countries.length)];
const randomOpt1 = this.state.countries[Math.floor(Math.random()*this.state.countries.length)];
const randomOpt2 = this.state.countries[Math.floor(Math.random()*this.state.countries.length)];
const randomOpt3 = this.state.countries[Math.floor(Math.random()*this.state.countries.length)];
const randomOptions = [random.name, randomOpt1.name, randomOpt2.name, randomOpt3.name];
randomOptions.sort(() => { return 0.5 - Math.random() });
this.setState({
randomCountry: random,
randomOptions: randomOptions,
userIsWin: '',
disableFieldset: false
})
}
checkWin(e) {
this.setState({
disableFieldset: true
})
const winCountry = this.state.randomCountry.name;
const userGuess = e.target.value;
if (winCountry === userGuess) {
this.setState({
userIsWin: 'Win',
goodGuess: this.state.goodGuess + 1,
bgColor: {backgroundColor: '#81C784'}
})
} else {
this.setState({
userIsWin: 'Lose',
bgColor: {backgroundColor: '#FF8A65'}
})
}
setTimeout(()=>{
this.getRandomCountry();
this.setState({
userIsWin: '',
disableFieldset: false,
bgColor: {backgroundColor: 'white'}
})
console.log(e.target)
}, 2000)
}
render() {
return (
<div className="main" style={this.state.bgColor}>
<div className="wrapper">
<h1>Country Guessing Game</h1>
<button className="rnd mui-btn mui-btn--raised" onClick={this.getRandomCountry}>Random</button>
<div className="img-container">
<img className="mui-panel" src={this.state.randomCountry.flag} alt="Country flag" />
</div>
<h2>{this.state.userIsWin === 'Win' ? 'You guess right! ' : ''}
{this.state.userIsWin === 'Lose' ? 'You guess wrong. ' : ''}
Score:{this.state.goodGuess}</h2>
</div>
<fieldset disabled={this.state.disableFieldset}>
<form onClick={e => this.checkWin(e)}>
<button className="mui-btn mui-btn--raised" value={this.state.randomOptions[0]}>{this.state.randomOptions[0]}</button>
<button className="mui-btn mui-btn--raised" value={this.state.randomOptions[1]}>{this.state.randomOptions[1]}</button>
<button className="mui-btn mui-btn--raised" value={this.state.randomOptions[2]}>{this.state.randomOptions[2]}</button>
<button className="mui-btn mui-btn--raised" value={this.state.randomOptions[3]}>{this.state.randomOptions[3]}</button>
</form>
</fieldset>
</div>
)
}
}
export default Country;发布于 2018-01-05 06:02:13
屏幕设计看上去很漂亮。这是极简主义的,但令人愉快。它几乎完全适合我的手机的小屏幕(只是有时,我必须向下滚动,以看到所有的答案按钮)。这些标志非常大,可以探索精细的图形细节。为了欣赏尼泊尔国旗的形状,它周围不应该有边框,背景颜色可以设置为白色以外的东西,因为这是在一些旗帜中使用的。
错误:永远不要使用随机比较器进行排序。相反,对数组进行洗牌。这个问题经常已经得到了回答,只需搜索上面的术语。
当大声阅读代码时,“国家是一个组件”是没有意义的。国家是有名字和国旗的东西,所以最好把这个类命名为CountryComponent。
大多数JavaScript代码可以重写为不使用this关键字或bind函数,这将导致代码更清晰、更简单。有关示例,请参见此代码评审。
在setTimeout调用中,我更倾向于将第一个参数提取到一个命名函数中,以便setTimeout看起来更接近于2000:
function action() {}
setTimeout(action, 2000);在标签“得分:”和分数号之间应该有一个空格。
当我进行测验时,我的总分总是保持在0,所以一定有什么问题。每次点击一个答案按钮后,页面会在大约一秒内变成绿色或橙色,然后重新加载,这解释了分数被重置,屏幕闪烁。另一方面,随机按钮工作正常,所以它们之间肯定有一些不同之处。(在Android上用Firefox进行测试。)
发布于 2018-01-05 00:20:21
很好地使用箭头函数、fetch API (以及相关的承诺)等等。布局看起来也不错。
getRandomCountry()中的代码不考虑Math.floor(Math.random()*this.state.countries.length)在4个连续调用中产生相同值的情况。即使有250个选项,也有可能在选项列表中出现一个国家名称( 2+ )。可以使用一个循环来代替选择三个随机选项,直到选择了4个唯一的名称。
因此,代替了这些行:
const随机= this.state.countriesMath.floor(Math.random()*this.state.countries.length);const randomOpt1 = this.state.countriesMath.floor(Math.random()*this.state.countries.length);const randomOpt2 = this.state.countriesMath.floor(Math.random()*this.state.countries.length);const randomOpt3 = this.state.countriesMath.floor(Math.random()*this.state.countries.length);const randomOptions = 名称,随机Opt1.name,随机Opt2.name,随机Opt3.name;
使用while (或for)循环继续添加选项。在循环中,选择“随机”国家名,然后可以使用Array.includes()检查数组中是否已经存在每个随机名称:
const random = this.state.countries[Math.floor(Math.random()*this.state.countries.length)];
let randomOptions = [random.name];
while(randomOptions.length < 4 ){
const randomOpt = this.state.countries[Math.floor(Math.random()*this.state.countries.length)];
if (!randomOptions.includes(randomOpt.name)) {
randomOptions.push(randomOpt.name);
}
}虽然它没有什么问题,但它与颜色的规格不一致(例如,初始背景色的white,然后是#81C784表示win,或者#FFA865表示损失)。其他阅读您的代码的人可能会因为规范的不同而被抛之脑后。至少,在十六进制密码之后发表一句有用的评论可能会有帮助.例如:
bgColor: {backgroundColor: '#81C784'} //green和
bgColor: {backgroundColor: '#FFa865'} //orange发布于 2018-01-05 11:48:50
代码和游戏看起来都很好!我只想几句:
我不认为你需要:
this.getRandomCountry = this.getRandomCountry.bind(this);
this.checkWin = this.checkWin.bind(this);在类中,您可以调用自己的方法,而无需绑定它们。如果这给了你一个错误,你可能失去了其他地方的范围
class Thing {
constructor(){
this.doThing()
}
doThing(){
}
}你可以让“赢”成为一个布尔值,并将它用于正反两方面:
<h2>{(this.state.userIsWin) ? 'You guess right! ' : 'You guess wrong.'}</h2>https://codereview.stackexchange.com/questions/184324
复制相似问题