作业前准备
React在他的官网上挂了一个入门教程,是做一个xxoo棋的小游戏,在教程的最后留下了6个作业题,现在就来完成一下
准备材料
作业是在已完成教程的基础上做的,所以这里预设已经做好了环境部署,写好了游戏代码(如果没有,可以把这个复制进去),并成功运行了该游戏,如果上面的都准备就绪,那我们就可以开动了
第一题 在游戏历史记录列表显示每一步棋的坐标,格式为 (列号, 行号)
历史记录是保存为数组history的,数组的每一个元素表示每一步棋,现在的要求是对于每一步棋,不仅要显示棋盘的布局(数组squares),还要显示这步棋下在了哪里了,那我们就对【每步棋】这个对象再添加一个坐标(行号row,列号col)
首先,在构造函数constructor中修改代码如下
constructor(props) {
super(props);
this.state = {
history: [{
squares: Array(9).fill(null),
//在这里添加两个新属性,行号和列号 row: null,
col: null,
}],
stepNumber: 0,
xIsNext: true,
}
}
然后,在每次点击棋盘格子时,会触发handleClick()方法,该方法会改变state的值,其中也包括新添加的坐标,所以我们修改handleClick()方法下的this.setState()方法如下
this.setState({
history : history.concat([{
squares : squares,
//这里分别拿格子编号i对棋盘的大小3做商和取余,得到行号和列号 row: parseInt(i/3)+1,
col: i%3+1,
}]),
stepNumber : history.length,
xIsNext : !this.state.xIsNext,
});
最后,我们需要在渲染的时候,把坐标显示出来,修改render()方法下的moves如下
const moves = history.map((step, move) => {
//修改描述文字,在步数move后面加入坐标(行号,列号) const desc = move ?
'Go to move #' + move + ' (' + step.row + ',' + step.col + ')':
'Go to game start';
return (
this.jumpTo(move)}>{desc}
);
});
题目要求格式为 (列号, 行号),但个人感觉行号在前,列号在后更好理解吧。。所以修改了设计
另外这里用到了一个map方法,他可以把一个序列变换成另一个序列,变换的方法是写在形如(x) => {return x;} 的闭包里,其中的x表示序列中的一个元素,在下棋的例子里,对序列history做变换,step就表示每一步棋,所以step具有每步棋的坐标属性
保存,测试一下效果如下,成功
PS 第一问就写这么长,考虑要不要每题都分开写。。。
第二题 在历史记录列表中加粗显示当前选择的项目
这里涉及到条件渲染,如果【这步棋】是当前步(current),那么加粗他,否则不加粗,修改render()方法下的moves如下
const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move + ' (' + step.row + ',' + step.col + ')':
'Go to game start';
//判断是否是当前步,返回加粗或不加粗的组件 if(step === current) {
return (
this.jumpTo(move)}>{desc}
);
} else {
return (
this.jumpTo(move)}>{desc}
);
}
});
加粗显示就简单的用标签实现,最终显示效果如下
第二题还蛮简单的。。