因?yàn)闃I(yè)務(wù)需求,公司決定改版官網(wǎng)的技術(shù)架構(gòu),最終選定用React。
前幾個(gè)星期剛學(xué)習(xí)了點(diǎn)React就被新需求拉回去加班了,因此React的學(xué)習(xí)也就停下來了,最近幾天不那么忙了,利用回家后的時(shí)間把最近的一個(gè)小需求用React實(shí)現(xiàn)。
從純React(無webpack, router)開始。
參考這個(gè)簡(jiǎn)單易懂的教程:react-from-zero
前提:
- 之前的學(xué)習(xí)讓我對(duì)React的理念和語法有了一些基本的了解了。
-
現(xiàn)在的需求我白天在公司已經(jīng)用html+css+js實(shí)現(xiàn)一次了。
js實(shí)現(xiàn)效果
以下為我思考與操作的流程:
- 把上面教程里的所有demo復(fù)制到本地,看注釋和代碼,跑一遍。
- 分析頁面元素
2.1.頭像圖片
2.2.選擇按鈕
2.3.頭像組
2.3.1.頭像圖片5
2.4.輸入框3
2.4.1.輸入框按鈕
2.5.報(bào)名按鈕 - 把css文件引入,運(yùn)行,沒問題,背景圖出現(xiàn)了
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
<title>test</title>
<script src="http://cdn.bootcss.com/react/0.14.7/react.js"></script>
<script src="http://cdn.bootcss.com/react/0.14.7/react-dom.js"></script>
<script src="http://cdn.bootcss.com/babel-core/5.8.23/browser.min.js"></script>
<link rel="stylesheet" href="./test.css" />
<script type="text/babel">
</script>
4.添加頭像,在script標(biāo)簽中加入頭像代碼
function Image(props){
return (<img className={props.className} src={props.src} />);
}
var reactElement =
<div className="container">
<Image className="my-avatar" src="../avatar-1.png" />
</div>;
var renderTarget = document.body;
ReactDOM.render(reactElement, renderTarget);

5.添加選擇按鈕(略過),添加頭像組,script代碼如下
頭像組代碼寫法參照上面demo的第五個(gè)example
function Image(props){
return (<img className={props.className} src={props.src} />);
}
//增加以下組件-start
var avatarPics = ["1","2","3","4","5"];
var avatarArr = avatarPics.map(function(avatar){
return (<Image src={"../avatar-"+avatar+".png"} />);
});
function AvatarsBox(props){
return (
<div className={props.className}>
{avatarArr}
</div>);
}
//增加以下組件-end
var reactElement =
<div className="container">
<Image className="my-avatar" src="../avatar-1.png" />
<Image className="slc-btn" src="../slc-btn.png" />
<AvatarsBox className="avatars" />
</div>;
var renderTarget = document.body;
ReactDOM.render(reactElement, renderTarget);

6.添加輸入框和底部按鈕
function Image(props){
return (<img className={props.className} src={props.src} />);
}
var avatarPics = ["1","2","3","4","5"];
var avatarArr = avatarPics.map(function(avatar){
return (<Image src={"../avatar-"+avatar+".png"} />);
});
function AvatarsBox(props){
return (
<div className={props.className}>
{avatarArr}
</div>);
}
//輸入框-start
function InputBox(props){
return (
<div className={props.className+ ' ' +props.id}>
<input id={props.id} type={props.type} />
//下面這個(gè)屬性下一頁會(huì)講到
{props.children}
</div>);
}
//輸入框-end
var reactElement =
<div className="container">
<Image className="my-avatar" src="../avatar-1.png" />
<Image className="slc-btn" src="../slc-btn.png" />
<AvatarsBox className="avatars" />
<InputBox className="input-box" id="name" type="text" />
<InputBox className="input-box" id="phone" type="number" />
<InputBox className="input-box" id="code" type="number" />
<Image className="join-btn" src="../join-btn.png" />
</div>;
var renderTarget = document.body;
ReactDOM.render(reactElement, renderTarget);

7.開始添加驗(yàn)證碼按鈕(點(diǎn)擊disabled, 60秒倒計(jì)時(shí)),可參考demo-9
把demo-9里的代碼拷貝到本地,注釋全部刪掉,MyComponent里的方法從第一個(gè)開始刪,最后只留下getInitialState,handleClick,render,代碼就清晰明了了
新組件代碼如下:
//開發(fā)過程如下:
//1. handleClick只放置this.setState({enable:false}), 測(cè)試禁用效果通過
//2. 加入計(jì)時(shí)器,測(cè)試計(jì)時(shí)器通過
var InputBtn = React.createClass({
getInitialState: function(){
return {
countdown: "驗(yàn)證碼",
enable: true
}
},
handleClick: function(){
this.setState({
countdown: 59,
enable: false
});
//此處切記,在setInterval里,this指的是計(jì)時(shí)器的作用域,因此用that表示click的作用域
var that = this;
var timeCounter= setInterval(function(){
that.state.countdown--;
if(0===that.state.countdown){
that.setState({
countdown: "驗(yàn)證碼",
enable: true
});
clearInterval(timeCounter);
}else{
//不知道有forUpdata()這個(gè)方法,抱著試一下的想法是用了不帶參數(shù)的setState()來刷新,chrome控制臺(tái)提示我應(yīng)該用forceUpdate()
//一開始用的是that.setState();
that.forceUpdate();
}
},1000);
},
render: function(){
return <button onClick={this.handleClick} disabled={!this.state.enable}>{this.state.countdown}</button>
}
});
var reactElement =
<div className="container">
<Image className="my-avatar" src="../avatar-1.png" />
<Image className="slc-btn" src="../slc-btn.png" />
<AvatarsBox className="avatars" />
<InputBox className="input-box" id="name" type="text" />
<InputBox className="input-box" id="phone" type="number" />
<InputBox className="input-box" id="code" type="number" >
//給這里加上新加的驗(yàn)證碼組件,這面的InputBtn標(biāo)簽就是上一頁里的{props.children}
<InputBtn text="驗(yàn)證碼"/>
//這個(gè)地方把輸入框給關(guān)閉了
</InputBox>
<Image className="join-btn" src="../join-btn.png" />
</div>;

總結(jié):
學(xué)習(xí)的過程就是模仿與蓋房子,模仿就是模仿別人的寫法,直接把代碼copy過來改也行(但是還是自己寫的好);蓋房子就是一塊一塊磚頭往上壘:
頭像-選擇按鈕-頭像組-輸入框-驗(yàn)證碼按鈕-驗(yàn)證碼按鈕禁用-驗(yàn)證碼倒計(jì)時(shí)
一步一步,最后就成了一個(gè)完整的頁面了。切莫覺得這一步一步你都會(huì),就像直接跳過,蓋房子嘛,還是得一塊一塊磚頭來。
2016.04.28 首開
