react:官方引导文件 学习笔记(一)
目标:开发一款三连旗小游戏
一、先决条件
懂html和js,熟悉一种编程语言,会使用es6的箭头函数,let,const,class,等新特性.
二、安装
(1)可以使用官方提供的在线编辑器Starter Code
(2)可以本地化安装:
第一步:安装node.js
第二步:安装create-react-app,并新建项目
npm install -g create-react-app create-react-app my-app
第三步:删除src文件夹中的所有内容
第四步:新建一个index.css文件,并将下面内容复制到改文件
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}
ol, ul {
padding-left: 30px;
}
.board-row:after {
clear: both;
content: "";
display: table;
}
.status {
margin-bottom: 10px;
}
.square {
background: #fff;
border: 1px solid #999;
float: left;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 34px;
margin-right: -1px;
margin-top: -1px;
padding: 0;
text-align: center;
width: 34px;
}
.square:focus {
outline: none;
}
.kbd-navigation .square:focus {
background: #ddd;
}
.game {
display: flex;
flex-direction: row;
}
.game-info {
margin-left: 20px;
}
第五步:创建一个index.js文件,并将下面的代码粘贴到index.js
class Square extends React.Component {
render() {
return (
<button className="square">
{/* TODO */}
</button>
);
}
}
class Board extends React.Component {
renderSquare(i) {
return <Square />;
}
render() {
const status = 'Next player: X';
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(
<Game />,
document.getElementById('root')
);
第六步:添加三行引入语句到index.js的顶部
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css';
这样,在你的工程文件夹内,启动项目:
npm start
然后就可以在自己的浏览器中看到空白的棋盘项目。
建议调整你的编辑器,以便可以使得语法高亮显示,atom的话安装apm install language-babel
什么是react?
react 是一种用组件来展示应用前端的工具。每当数据变化时,react会自动更新组件,并展示出来。
react最基本组成是component(组件),每个组件可以携带属性(props),并渲染一定的内容通过render方法返回(return)。
审查原始代码:
1、创建了三个组件:square(方块组件,返回一个button),board组件返回9个square,game组件返回一个board
2、css样式已经设置好,因此在本案例中仅需关心与react相关的内容
现在展现的是一个静态的面板,还没有互动环节。
通过props进行传值
在board中传给square以value属性,然后在square中使用this.props.value接受父组件传递过来的值。
在react中,父组件是通过props向子组件传值的。
创建一个交互的组件
组件(component)使用私有的state保存自己的状态,当希望改变组件的状态时,就是改变组件的state中的属性。
本例中我们希望在点击button时候,让botton的值为X
这时我们在button上绑定一个监听事件onClick当点击按钮的时候,调用一个处理函数将square的state中的value的值变为“X”,然后将Value的值传递给button
在chorm中检查你的react组件
在应用商店中安装react-devtools。就可以向检查网页一样检查react组件树了
在父组件中保存子组件的状态
由于我们需要知道9个square的状态,而每个square只知道自己的状态,因此为了知道9个组件共同的状态,我们将所有子组件的状态上移至父组件中,然后父组件可以通过props与子组件进行交互传值。
每当子组件之间需要交互,或者需要保存多个子组件的状态时,我们就需要将所有子组件的状态上移至父组件。
再次改变组件的状态
现在由于子组件不在保存自己的状态,而是通过父组件的props获取状态,而子组件无法直接修改父组件的私有的state,因此我们就需要一个回调函数解决该问题:
在父组件中为子组件增加 一个props对应的函数,每当子组件需要修改该状态时,就调用该函数。
子组件square的button的click时间调用board传递给他的props.func(),父组件的func()调用的handlefunc()方法修改父组件中的state,然后所有的子组件状态便会得到修改。
现在square从父组件接受数据,并且在收到点击后通知父组件board进行处理,这样的组件在react中叫做controlled component
不要直接改变state的值
当state中数据为对象或数组时,不要直接改变数组或对象的值,而是应该通过obj.assign({}/[],origin,news)来创建一个新的数组或对象。
这样的好处是:(1)我们建立了一个pure component,这样我们可以决定何时re-render一个新的组件,shoudCompoentUpdate()。
(2)我们可以更加方便的比较组件之间的区别。
(3)可以保存组件不同时期的state,便于回溯。
方法组件
对于controlled component 我们可以把其写为含有props参数的函数组件。仅仅实现return方法,不用保留自己的状态。
切换状态
我们需要第一个人输入“X”之后,另一个人只能输入“O”,这时我们就需要保存游戏中游戏者的状态,通过在board中增加一个游戏状态,每当square的button被点击的时候,游戏状态便变动一次。
宣布获胜者
制定获胜规则,每当三个连线成功时,一方获胜。则游戏结束,无法再次点击。每次处理点击事件时应该查看是否已经获胜,或者已经有值。
添加查看下棋历史步骤功能
为了查看所有的历史步骤,我们需要保存所有的board的状态,这时我们就需要再次将board维护的state交由game来维护,
board不需要constructor,相应的状态全部由game维护,game传递squrares和处理onClick函数。
status也由game来维护。
显示历史步骤
使用map函数将所有的history对应的步骤显示出来;
注意这里传递的列表元素,需要为每个元素增加一个key,以便于react可以识别、修改元素
跳转至指定步骤
增加一个state状态记录指定步骤stepNumber,使用stepNumber显示history
浙公网安备 33010602011771号