第一次用React写一个小demo

145 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情

前言

最近趁上班空闲的时候比较空闲,由于只会用Vue的原因,所以也想学学新的知识,于是想自学一下React,打开React的官网发现React的新手教程相对于Vue来说是比较友好的,可以有俩种学习的方式,可以从基础开始学习,也可以从一个demo开始学习,于是选择了从demo开始出发,最后也做了一个改版。

React工具

React 有个比较好的调试方案,那就是官方文档指出的 react devtools ,可以针对性的做一些代码的调试。所以我可以安装了个插件玩玩

image.png

chorme的网上商店需要科学上网才能得到,如果检测到当前web是 react 项目,右上角的工具小图标(地址栏右侧)会发生改变,这样我们打开控制台就可以看到整个react的树结构,有利于我们开发的时候更好的处理问题。

小demo

image.png

这个是利用了官方提供的demo的模板,我将九宫格的小游戏改成了一个九宫格转盘游戏,点击开始游戏的时候红色方块会在九宫格中随机跳动,后续将给他改成一个打地鼠的游戏。

React的结构

React整个项目的入口和vue没什么区别,都通过一个index.html当做如果,然后按照官方文档的教程,在src文件夹下新建index.js和index.css,而没有html文件,一些dom都是通过JSreturn的方式返回的。react的组件化我感觉比vue的更加明显一点,主要是通过render先返回一个作为父组件的dom,父组件的dom中也可以放一个子组件,整个Game的类作为一个父组件,通过ReactDOM.render的方式显示到页面上,在Game的类中我们可以写一些函数,比如我写的restart函数,通过constructor可以继承一些父组件传过来的数据,也可以设置一些state数据作为共享数据使用

  class Game extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            history: [{
                square: Array(9).fill(null),
            }],
            // stepNumber: 0,
            xIsNext : true,
            activeIndex:1
        }
    }
    restrat() {
      setInterval(() => {
        this.setState({
          activeIndex:Math.round(Math.random()*8+0)
        })
        console.log(this.state.activeIndex)
      }, 250);
    }
  render() {
      const history = this.state.history;
      return (
          <div className="game">
          <div className="game-board">
              <Board 
                  activeInd={this.state.activeIndex}
              />
          </div>
          <div className="game-info">
          </div>
          <div>
            <button onClick={()=>this.restrat()} >开始游戏</button>
          </div>
          </div>
      );
    }
  }
ReactDOM.render(
    <Game />
    ,
    document.getElementById('root')
);

又比如我在Board中设置了renderSquare函数,在render的中返回的dom中又可以用到自己的函数,并且可以通过父组件返回的数据做判断,这里我是判断当前随机的index是否和九宫格的index是否相同,然后去改变背景颜色

  class Board extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            square  : Array(9).fill(null),
            xIsNext : true,
        }
    }
    renderSquare(i) {
        if(this.props.activeInd==i){
            return <Square 
                activeClass = 'active'
                value1={this.props.activeInd}
            />;
        }else{
            return <Square 
            />;
        }
      
    }
  
    render() {
      return (
        <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>
      );
    }
  }

最后是一个子组件是小格子的,react的组件不仅可以通过类返回,也可以通过function的方式,然后是返回动态节点的格式,{props.value} {props.value1?

: ''},中间的style格式也是通过先声明一个样式sty对象,然后再通过模板语法进行显示

function Square(props) {
    let imgUrl = './mouse.jpg'
    let sty = {
      background:'red',
      height: '100%',
      width: '100%'
    }
    return (
    <div className="square" >
        {props.value}
        {props.value1
          ? <div style={sty}></div>
          : ''
        }
    </div>

    );
}

到这里三个组件已经做完了,Game也被显示到页面上,至此整个页面也已经完成我们可以看看效果

667.gif 把主要文件给大家分享一下

//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;
  }
  .activeClass{
      background-color: red;
  }
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
    function Square(props) {
        let imgUrl = './mouse.jpg'
        let sty = {
          background:'red',
          height: '100%',
          width: '100%'
        }
        // const changeSty = {props.value1?sty:''}
        return (
        <div className="square" >
            {props.value}
            {props.value1
              ? <div style={sty}></div>
              : ''
            }
        </div>

        );
    }
  class Board extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            square  : Array(9).fill(null),
            xIsNext : true,
        }
    }
    renderSquare(i) {
        if(this.props.activeInd==i){
            return <Square 
                activeClass = 'active'
                value1={this.props.activeInd}
            />;
        }else{
            return <Square 
            />;
        }
      
    }
  
    render() {
      return (
        <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 {
    constructor(props){
        super(props);
        this.state = {
            history: [{
                square: Array(9).fill(null),
            }],
            // stepNumber: 0,
            xIsNext : true,
            activeIndex:1
        }
    }
    restrat() {
      console.log(222);
      setInterval(() => {
        this.setState({
          activeIndex:Math.round(Math.random()*8+0)
        })
        console.log(this.state.activeIndex)
      }, 250);
    }
  render() {
      const history = this.state.history;
      return (
          <div className="game">
          <div className="game-board">
              <Board 
                  activeInd={this.state.activeIndex}
              />
          </div>
          <div className="game-info">
          </div>
          <div>
            <button onClick={()=>this.restrat()} >开始游戏</button>
          </div>
          </div>
      );
    }
  }
  
  // ========================================
  
  ReactDOM.render(
    <Game />
    ,
    document.getElementById('root')
  );
  function calculateWinner(square) {
    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 (square[a] && square[a] === square[b] && square[a] === square[c]) {
        return square[a];
      }
    }
    return null;
  }