React 從院子到入門(一)

因?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

前提:

  1. 之前的學(xué)習(xí)讓我對(duì)React的理念和語法有了一些基本的了解了。
  2. 現(xiàn)在的需求我白天在公司已經(jīng)用html+css+js實(shí)現(xiàn)一次了。


    js實(shí)現(xiàn)效果

以下為我思考與操作的流程:

  1. 把上面教程里的所有demo復(fù)制到本地,看注釋和代碼,跑一遍。
  2. 分析頁面元素
    2.1.頭像圖片
    2.2.選擇按鈕
    2.3.頭像組
    2.3.1.頭像圖片5
    2.4.輸入框
    3
    2.4.1.輸入框按鈕
    2.5.報(bào)名按鈕
  3. 把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);
有了輸入框和底部按鈕(頭像組被我css控制隱藏了)

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>;
驗(yàn)證碼倒計(jì)時(shí)的交互也OK了

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

2016.04.28 首開

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容