首页 > 其他分享 >简单记录-react学习,用函数式组件写井字棋

简单记录-react学习,用函数式组件写井字棋

时间:2022-09-26 14:44:32浏览次数:82  
标签:const renderSquare 写井字 react props 组件 return squares ihistory

React官方给定的教程,井字棋(tic-tac-toe),是使用 class 组件制作的,但是函数式组件才是未来,所以初学者的我用函数式组件重写一遍,简单记录一下。

官方教程链接

import React, {useState} from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';


function Square(props) {
    return (
        <button className="square" onClick={props.onClick}>
            {props.value}
        </button>
    );
}

function Board(props) {

    const renderSquare = (i) => (
        <Square
            value={props.squares[i]}
            onClick={() => props.onClick(i)}
        />
    );

    return (
        <div>
            <div className="board-row">
                {renderSquare(0)}
                {renderSquare(1)}
                {renderSquare(2)}
            </div>
            <div className="board-row">
                {renderSquare(3)}
                {renderSquare(4)}
                {renderSquare(5)}
            </div>
            <div className="board-row">
                {renderSquare(6)}
                {renderSquare(7)}
                {renderSquare(8)}
            </div>
        </div>
    );
}

function Game(props) {
    const [history, setHistory] = useState([{
        squares: Array(9).fill(null),
    }]);
    const [stepNumber, setStepNumber] = useState(0);
    const [xIsNext, setXIsNext] = useState(true);


    const handleClick = (i) => {
        const ihistory = history.slice(0, stepNumber + 1);
        const current = ihistory[ihistory.length - 1];
        const squares = current.squares.slice();
        if (calculateWinner(squares) || squares[i]) {
            return;
        }
        squares[i] = xIsNext ? 'X' : 'O';
        setHistory(ihistory.concat([{ squares: squares }]));
        setStepNumber(ihistory.length);
        setXIsNext(!xIsNext);
    }

    const jumpTo = (step) => {
        setStepNumber(step);
        setXIsNext((step % 2) === 0);
    }

    const render = () => {
        const ihistory = history;
        const current = ihistory[stepNumber];
        const winner = calculateWinner(current.squares);

        const moves = ihistory.map((step, move) => {
            const desc = move ?
                'Go to move #' + move :
                'Go to game start';
            return (
                <li key={move}>
                    <button onClick={() => jumpTo(move)}>{desc}</button>
                </li>
            );
        });


        let status;
        if (winner) {
            status = 'Winner: ' + winner;
        } else {
            status = 'Next player: ' + (xIsNext ? 'X' : 'O');
        }


        return (
            <div className="game">
                <div className="game-board">
                    <Board
                        squares={current.squares}
                        onClick={(i) => handleClick(i)}
                    />
                </div>
                <div className="game-info">
                    <div>{status}</div>
                    <ol>{moves}</ol>
                </div>
            </div>
        );
    }

    return render();
}


function calculateWinner(squares) {
    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 (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
            return squares[a];
        }
    }
    return null;
}

// ========================================

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Game />);

标签:const,renderSquare,写井字,react,props,组件,return,squares,ihistory
From: https://www.cnblogs.com/amtop/p/16730916.html

相关文章

  • 给组件input/input-number做校验 vue antd
    input校验<a-inputv-model="formState.collectCardNum"placeholder="请输入"oninput="value=value.replace(/[^\w\.......
  • Blazor中CSS隔离无法用在Masa Blazor组件上
    最近新学了Blazor,使用了MasaBlazor。Blazor的CSS隔离是个很好的东西,如图,只需添加一个与Razor组件同名的CSS文件,这个文件中的CSS样式只会在同名的Razor组件中使用。原理......
  • 我如何在 React 中使用条件渲染
    我如何在React中使用条件渲染如果使用得当,条件渲染是一个非常有用的React概念。您可以根据是否满足某些条件来决定要渲染哪些组件,或者可能完全忽略一个组件。我将举例......
  • React-Native 中关于 useEffect 钩子的完整指南
    React-Native中关于useEffect钩子的完整指南本指南将提供有关react-native中useEffect挂钩的完整信息。同样的概念也可以应用于反应。在React-Native应用程序......
  • react组件深度解读
    五、React核心是组件在React中,我们使用组件(有状态、可组合、可重用)来描述UI。在任何编程语言中,你都可以将组件视为简单的函数。React组件也一样,它的输入是props......
  • React核心技术浅析
    1.JSX与虚拟DOM我们从React官方文档开头最基本的一段HelloWorld代码入手:ReactDOM.render(<h1>Hello,world!</h1>,document.getElementById('root'));这段......
  • react的jsx语法是怎样解析的
    首先我们来看看下面的代码import"react"from"react";constelement=(<div><div><span>1</span><span>2</span>......
  • reactor的三种模式
    Reactor响应式编程,是NIO的编程设计模式 单reactor单线程模式:简单NIO例子中,选择器循环和业务处理线程都用一个线程。也是最简单的NIO编程模式。   单Reacto......
  • react脚手架搭建的几种方式
    react脚手架创建几种方式nodev16.17.0npm8.15.0yarn3.2.3vite3.1.3配置less-loadernpm首先通过npm方式全局安装create-react-appnpminstall-gcrea......
  • Vue 组件component定义和调用
    <divid="app"><itembox></itembox></div><script>Vue.component("itembox",{template:"<h2>www.gzsmbj.com</h2>"})newVue({el:"#app", data:{ title:'11......