React入门(四)

  React入门(四)


  本节我们为上例的程序加上一些新功能:轮流行动和判断胜负。


  一、轮流行动


  前面的程序每次点击格子,都显示“叉”。我们需要一次显示“圈”,一次显示“叉”。


  这里在状态中增加一个布尔型变量,如果上一次是true,这一次就是false;如果是true,就显示“叉”,如果是false,就显示“圈”。


  修改一下Board类的代码:


class Board extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: Array(9).fill(null),
            xIsNext: true, // 添加一个布尔型变量,用于表示轮流行动
        };
    }

    handleClick(i) {
        const data = this.state.data.slice();
        data[i] = this.state.xIsNext ? 'X' : 'O'; // 根据布尔型变量,显示“叉”还是“圈”
        this.setState({
            data: data,
            xIsNext: !this.state.xIsNext, // 修改布尔型变量,直接进行非运算
        });
    }

    renderSquare(i) {
        return (
            <Square
                value={this.state.data[i]}
                onClick={() => this.handleClick(i)}
            />
        );
    }

    render() {
        const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');

        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>
        );
    }
}

   运行结果如下:




  二、判断胜负


  为了判断胜负,我们写了一个函数,放在文件的最后部分:


ReactDOM.render(
    <Game />,
    document.getElementById('root')
);

function calculateWinner(data) { // 判断胜负
    const lines = [
        [0, 1, 2], // 横
        [3, 4, 5], // 横
        [6, 7, 8], // 横
        [0, 3, 6], // 竖
        [1, 4, 7], // 竖
        [2, 5, 8], // 竖
        [0, 4, 8], // 对角线
        [2, 4, 6], // 对角线
    ];
    for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        if (data[a] && data[a] === data[b] && data[a] === data[c]) {
            return data[a];
        }
    }
    return null;
}

  这个函数的算法我们解释一下。

  首先,函数的参数就是如下数组:

[
  'O', null, 'X',
  'X', 'X', 'O',
  'O', null, null,
]

  以前,我们解释过tic-tac-toe的游戏规则,就是横、竖、对角线形成三连。

  这里,我们定义一个数组lines,把所有获胜的场景都罗列出来,包括横、竖、对角线。

  接下来,就是判断获胜方是谁,函数的返回值是“圈”、“叉”、null,返回null表示无人获胜。

    for (let i = 0; i < lines.length; i++) { // 遍历数组
        const [a, b, c] = lines[i]; // 使用解构赋值,把数组一行中的元素赋值给a、b、c
        if (data[a] && data[a] === data[b] && data[a] === data[c]) { // 如果data[a]不为空,且一条直线上的值相同
            return data[a];
        }
    }

  有了这个函数,接下来就是利用这个函数进行胜负判断了,以下是完整代码:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class Square extends React.Component {
    render() {
        return (
            <button className="square" onClick={() => this.props.onClick()}>
                {this.props.value}
            </button>
        );
    }
}

class Board extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: Array(9).fill(null),
            xIsNext: true,
        };
    }

    handleClick(i) {
        const data = this.state.data.slice();
        if (calculateWinner(data) || data[i]) { // 如果已经有获胜者,或者该格子已经被点过,则忽略点击行为
            return;
        }
        data[i] = this.state.xIsNext ? 'X' : 'O';
        this.setState({
            data: data,
            xIsNext: !this.state.xIsNext,
        });
    }

    renderSquare(i) {
        return (
            <Square
                value={this.state.data[i]}
                onClick={() => this.handleClick(i)}
            />
        );
    }

    render() {
        const winner = calculateWinner(this.state.data); // 每次渲染前都判断胜负
        let status;
        if (winner) { // 如果winner不为空,则显示胜者,否则显示下一步的玩家
            status = 'Winner: ' + winner;
        } else {
            status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
        }

        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')
);

function calculateWinner(data) {
    const lines = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6],
    ];
    for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        if (data[a] && data[a] === data[b] && data[a] === data[c]) {
            return data[a];
        }
    }
    return null;
}


  运行结果如下:




  我们的React之旅到这里就告一段落了,这个小案例可以帮我们在React的路上前进一段。

  React官网上的案例比我们的这个案例多写了一些功能,有兴趣的朋友可以自己上官网研究一下。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React 是一个用于构建用户界面的 JavaScript 库。它被 Facebook 开发,用于构建 Facebook 和 Instagram 等应用程序的用户界面。React 通过组件化的方式构建用户界面,使得代码更易于维护和复用。下面是一个简单的 React 入门指南: 1. 安装 React React 可以通过 NPM 安装,可以在命令行中执行以下命令来安装 React: ``` npm install react react-dom ``` 2. 创建 React 组件 在 React 中,一个组件就是一个 JavaScript 类。下面是一个简单的组件示例: ```javascript import React from 'react'; class HelloWorld extends React.Component { render() { return <div>Hello World!</div>; } } export default HelloWorld; ``` 这个组件只是简单地渲染一个 `Hello World!` 的文本。 3. 渲染组件 要在页面中渲染组件,需要使用 `ReactDOM.render()` 方法。下面是一个简单的示例: ```javascript import React from 'react'; import ReactDOM from 'react-dom'; import HelloWorld from './HelloWorld'; ReactDOM.render( <HelloWorld />, document.getElementById('root') ); ``` 这个示例中,我们首先导入了 `ReactDOM` 和 `HelloWorld` 组件,然后使用 `ReactDOM.render()` 方法将 `HelloWorld` 组件渲染到页面上。在这个示例中,我们将组件渲染到了一个 ID 为 `root` 的元素中。 这只是 React入门React 还有很多其他的概念和功能,比如 JSX、状态、生命周期等等。如果您想深入了解 React,可以查看 React 官方文档,里面有很多有用的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值