在开始之前
我们在创建什么
我们先来开发一个交互的井字棋游戏.
如果你喜欢,你可以直接查看最终项目代码Final Resul.无需担心你现在是否明白理解里面的代码,或者是一些你不熟悉的语法。我们将一步步学习如何制作这个游戏。
玩一下这个游戏,还可以使用悔棋.
好了让我们开始教程.
必备条件
我们必须架设你首先对HTML和JavaScript很熟悉,不过即使不懂也没关系.
如果你是个js新人,推荐你阅读这个this guide. 提示一下我们会使用许多ES6特性,当前JS版本。这个教程将会用到arrow functions, classes,let 和const声明。
你可以使用 Babel REPL 检查ES6代码会编译成什么。
如何跟进
两个方法完成这个教程:你可以使用浏览器写代码或者 在机器上建立一个开发环境,两个都行,随你喜欢。
你喜欢在浏览器里写代码的话
This is the quickest way to get started!
最快的开发方法。(括弧笑)
打开starter code,然后跟着教程写代码就行。
你可以跳过下面设置开发环境了。
如果你希望在IDE里写代码
你可以在电脑里构建项目
步骤:
- Ma安装Node.js 略.
- 输入以下命令.
npm install -g create-react-app
create-react-app my-app
- 删除所有src/文件夹下的内容.
cd my-app
rm -f src/*
- 添加一个index.css到src/ 代码如下
-
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到src/代码如下 this JS code.
-
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') );
- 添加如下三行代码到 src/ index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
现在使用npm start来启动项目,打开http://localhost:3000网址,你会见到一个空的井字棋的页面。
遇到了不懂的问题
有条件就谷歌,没有就百度吧。
概览
什么是React?
React是高效灵活开源的JavaScript库,目的是创建用户界面。
React有几个不同的组件,我们会先从React.Component子类开始:
class ShoppingList extends React.Component {
render() {
return (
<div className="shopping-list">
<h1>Shopping List for {this.props.name}</h1>
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
<li>Oculus</li>
</ul>
</div>
);
}
}
// Example usage: <ShoppingList name="Mark" />
我们会写一个类似XML风格的代码组件。
你的组件告诉React你想渲染什么,然后当数据改变就更新渲染。
这里,ShoppingList是一个React组件类或者类型。传入的参数叫props然后通过render方法返回一个视图层。
render方法会绘制内容。一般返回的是React element,一个轻量的绘制描述。
React开发者会使用一个语法叫做JSX,可以容易的完成3个结构。
<div />会在构建的时候变成React.createElement('div')
例子如下:
return React.createElement('div', {className: 'shopping-list'},
React.createElement('h1', /* ... h1 children ... */),
React.createElement('ul', /* ... ul children ... */)
);
查看完成版本 See full expanded version.
如果你好奇 createElement()的更多信息你可以查看API API reference 在此不多说。
你可以放任何JS语法到JSX里。每个React element 是一个真实的JS对象,可以保存变量,传递。
ShoppingList
只渲染了内置DOM,不过想要调用自定义组件也很简单比如调用ShoppingList就使用<ShoppingList />
每个组件可以封装然后独立操作,可以通过简单组件构建复杂的UI。
开始
查看创建的项目代码。
CSS已经提供了,在此基础上只是开发JS。
一般,这里有3个组件:
- 方格
- 面板
- 游戏
方格组件只负责绘制<button>, 面板绘制9个方格,游戏组件绘制面板和一些占位符。所有的组件都还没有交互功能。
通过Props传数据
(俚语懒得翻译了)。我们先试试传些数据,从面板传给方格。
在面板的renderSquare方法,修改代码传如一个value到方格。
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
然后修改方格的render方法如下
class Square extends React.Component {
render() {
return (
<button className="square">
{this.props.value}
</button>
);
}
}
之前:
之后:
一个交互组件
React组件可以设置this.state在构造函数里。是组件的私有的。
在JS类中,当定义一个子类,必须在构造函数里声明super();ES6特性
修改代码如下:
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button className="square" onClick={() => this.setState({value: 'X'})}>
{this.state.value}
</button>
);
}
}
每次点击后,this.setState会修改value的值。显示‘X’。