React学习之围棋记谱本制作二棋盘、棋子、交替落子

  与儿子一起学围棋,上网上找,发现好用的记谱本软件特别少,打算自己做一个。不知能不能克服惰性,完成这个目标。
  千里之行,始于足下,今天完成了基础工作:棋盘、棋子组件,并完成了交替落子功能。是React基本功能的很好示范,代码贴一下。下一步就是多组件的状态管理、共享了。
  这里刚开始使用的是全局变量来管理状态,后来发现这是一个不太对路的方法,后来改用了全局的一个状态管理类来统一管理状态、处理状态变化、订阅监听、激活事件,后面的文章会介绍。

一、组件go.js
  想出了一个简单的、避免反复修改DOM的办法,将所有棋子组件在初始化都生成,通过状态控制其是否显示、响应点击事件。
var React = require('react');
var ReactDOM = require('react-dom');
require('../../../css/go.css');

//全局变量
window.gGoConfig = new GoConfig();

class GoConfig{
	constructor(){
		this.index=0;
		this.black=true;
	}
	
	inc(){
		this.index++;
		this.black=!this.black;
		console.log(this);
	}
}

//围棋桌面
class GoDesk extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            refresh: false
        };
    }

    render() {
        var self = this;
        this.state.refresh=false;
        var pieces = [];
        for (var i=0; i<19*19; i++){
        	pieces.push(
        		<GoPiece color={i % 2==0 ? 'white':'black'} id={'go'+(i+1)} key={'go'+(i+1)}/>
        	);
        }
        return <div className="go-desk">
        	<div className="go-opr">
	        	<GoBtn title="黑走"/>
	        	<GoBtn title="白走"/>
	        	<GoBtn title="黑子"/>
	        	<GoBtn title="白子"/>
        	</div>
        	<div className="go-board">
				{pieces}		        		
        	</div>
        </div>;
    }
}

//可以控制单个按钮的状态
class GoBtn extends React.Component{
	constructor(props){
		super(props);
		this.state={
			active:false,}
		this.clickHandle=this.clickHandle.bind(this);
	}
	
	clickHandle(event){
		this.setState({active:!this.state.active});
		console.log(this.state);
	}
	//<img src=img/{this.state.png} />
	render(){
		var className = "btn btn-default btn-sm";
		if(this.state.active==true)className = className+" active";
		return <button className={className} onClick={this.clickHandle}>{this.props.title}</button>;
	}
}

//使用bootstap的按钮组,可以不用控制按钮的状态,较为方便,还没有完全走通
class GoBtns extends React.Component{
	constructor(props){
		super(props);
		this.state={};
		this.clickHandle=this.clickHandle.bind(this);
	}
	
	clickHandle(idx){
		this.setState({index:idx});
	}
	render(){
		return <div class="btn-group" data-toggle="buttons">
				  <label class="btn btn-primary active"><input type="checkBox" autocomplete="off" checked />黑走(pre-checked)</label>
				  <label class="btn btn-primary"><input type="checkBox" autocomplete="off" />白走</label>
				  <label class="btn btn-primary"><input type="checkBox" autocomplete="off" />黑子</label>
				  <label class="btn btn-primary"><input type="checkBox" autocomplete="off" />白子</label>
				</div>;
	}
}

//棋子
class GoPiece extends React.Component{
	constructor(props){
		super(props);
		this.state={
			showNum:false,num:0,color:props.color,//or w
			current:false,visibility:'hidden',}
		
		//设置this,很重要
		this.handleClick=this.handleClick.bind(this);
	}
		
	handleClick(event){
		this.setState({
			visibility:this.state.visibility=='hidden'?'visible':'hidden',color:window.gGoConfig.black==true?'black':'white',});
		//console.log('click,visibility='+this.state.visibility);
		window.gGoConfig.inc();
	}
	
	render(){
		var className="go-piece go-piece-"+this.state.color;
		if (this.state.visibility=='hidden') className = className+" go-piece-hidden";
		//console.log(className);
		return <div className={className} id={this.props.id} onClick={this.handleClick}>
			<span style={{visibility:this.state.visibility}}>{this.state.num=window.gGoConfig.index}</span>
		</div>;// style={{visibility:this.state.visibility}}
	}
}

ReactDOM.render(
  <GoDesk />,document.getElementById('go-container')
);


二、样式文件go.css
.go-desk{
	background-image:url(../img/go/bk.png);
	width:100%;
	height:100%;
	padding:20px;
}

.go-opr{
	height:30px;
	text-align:center;
	margin-bottom:10px;
}

.go-board{
	width:800px;
	height:800px;
	margin:0 auto;
	background-image:url(../img/go/board.png);
	background-repeat:no-repeat;
	padding:20px;
}

.go-piece{
	width:40px;
	height:40px;
	float:left;
	background-image:url(../img/go/piece.png);
	text-align:center;
	line-height:40px;
	vertical-align:middle;
	font-size:20px;
}
.go-piece span{
}
.go-piece-white{
	background-position:-40px 0;
	color:black;
}
.go-piece-black{
	background-position:0 0;
	color:white;
}
.go-piece-hidden{
	background-image:none;

}


三、效果




四、全部代码   全部代码下载,请看系列文章第一部分,或点击:http://dl.iteye.com/topics/download/536961c7-38a6-38af-b034-c48034f2aa91

相关文章

一、前言 在组件方面react和Vue一样的,核心思想玩的就是组件...
前言: 前段时间学习完react后,刚好就接到公司一个react项目...
前言: 最近收到组长通知我们项目组后面新开的项目准备统一技...
react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...