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

 

posted @ 2018-08-02 18:41  tutu_python  阅读(149)  评论(0)    收藏  举报