日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > web前端 > htmlcss > react入門——實現一個輸入框組件

react入門——實現一個輸入框組件

來源:程序員人生   發布時間:2016-07-11 12:52:18 閱讀次數:6586次

React組件化開發初試

依照官方文檔和例程博客,實現了1個簡單的輸入框組件。

如果想了解官方案例,請參考深入理解 React

總結1下,1個簡單的React.js利用應依照以下步驟構建:

  1. 設計組件原型和JSON API;
  2. 拆分用戶界面為1個組件樹;
  3. 利用React, 創建利用的1個靜態版本;
  4. 辨認出最小的(但是完全的)代表UI的state;
  5. 確認state的生命周期;
  6. 添加反向數據流。

個人認為這里的難點在于如何拆分用戶界面,粒度過大不利于組件化的重用,粒度太小的話,顯得冗余過量,并且復雜度陡升。本人最開始嘗試細化的拆分,盡可能讓1個組件只完成1個很小的功能需求,但最后反而不知道如何給每一個組件分配其任務。

另外一個難點來源于對state的判斷,其實如果能夠辨認出最小的state,讀者會發現1個復雜的組件所需的state數量其實很少。

在React.js中,有兩種數據模型,state代表的是會動態變化的狀態,props代表的是父級傳遞而來的屬性,state會反過來更新UI,而props只是1次性設置填充。

第1步:構建原型

我們的組件要完成以下功能:

  1. 可以定制label和輸入框的placeholder的內容
  2. 可以有個屬性設置個正則,輸入的文字不符合正則的時候輸入框就標紅
  3. 右邊的大叉icon點擊后,消失并清楚輸入框內容
  4. 組件需要開放3個對外方法,獲得(獲得值時trim),設置(設置值時trim),刪除,輸入框的內容。

原型比較簡單,樣式以下:
LimitedInputBox

JSON接口數據以下:

{ labelText: "酒店地址", hinderText: "請填寫酒店地址", buttonImgSrc: regExp: /^\w{5,8}$/ }

我們通過JSON數據設置輸入框組件的label標簽、Input的placeholder屬性和對用戶輸入的正則驗證。

第2步:拆分用戶界面為1個組件樹

在完成用戶界面切分的進程中,最開始,如圖原型圖所示,做了非常細粒度的拆分,拆分結構以下:

  • LimitedInputBox
    • Title
    • InputBox
    • ClearButton

這里,將LimitedInputBox作為最外面的容器,包裹全部組件,子組件分為3部份,Title即是1個label標簽,用來顯示該輸入框組件的名稱(或說標題),InputBox即是1個input標簽,用來接收用戶輸入,ClearButton可以用1個img標簽,用來清除input輸入框內容。剛開始準備用另外1個容器包裹InputBoxClearButton,發現這樣過于冗余因而二者還是和Title作為同1級組件比較好。

后來思來,覺得過于拆分了,最小單位與HTML原生標簽同1級別,沒成心義,因此,最后只保存了1個組件,就稱之為LimitedInputBox。即:

  • LimitedInputBox

第3步:利用React, 創建利用的1個靜態版本

首先,不需要斟酌用戶交互,直接將數據模型渲染到UI上。行將數據渲染和用戶交互兩個進程拆分開來。

這樣做比較簡單,由于構建靜態版本的頁面只需要大量的輸入,而不需要思考;但是添加交互功能卻需要大量的思考和少許的輸入。

為了創建1個渲染數據模型的利用的靜態版本,你將會構造1些組件,這些組件重用其它組件,并且通過 props 傳遞數據。 props 是1種從父級向子級傳遞數據的方式。

本例中,的props就是第1步構建的JSON數據。

斟酌到第2步中我采取了兩種拆分方式,這里給出相應的代碼:

/** author : River He**/ //細分結構 var data = { labelText: "酒店地址", hinderText: "請填寫酒店地址", buttonImgSrc: "eliminate.png", regExp: /^\w{5,8}$/ }; var Title = React.creatClass({ render: function() { return ( <label>{this.props.labelText}</label> ); } }); var InputBox = React.createClass({ render: function() { return ( <input placeholder={this.props.hinderText} regExp={this.props.regExp}> </input> ); } }); var ClearButton = React.createClass({ render: function() { return ( <img src={this.props.buttonImgSrc}></> ); } }); var LimitedInputBox = React.createClass({ render: function() { return ( <Title labelText={this.props.data.labelText} /> <InputBox hinderText={this.props.data.hinderText} regExp={this.props.data.regExp} /> <ClearButton buttonImgSrc={this.props.data.buttonImgSrc} /> ); } }); ReactDOM.render( <LimitedInputBox data={data} />, document.getElementById('example') );
/** author : river he**/ //粗劃分 var data = { labelText: "酒店地址", hinderText: "請填寫酒店地址", buttonImgSrc: "eliminate.png", regExp: /^\w{5,8}$/ }; var LimitedInputBox = React.createClass({ render: function() { return ( <div> <label >{this.props.data.labelText}</label> <input placeholder={this.props.data.hinderText} regExp={this.props.data.regExp}> </input> <img src={this.props.buttonImgSrc ></img> </div> ); } }); ReactDOM.render( <LimitedInputBox data={data} />, document.getElementById('example') );

第4步:辨認出最小的代表UI的state

為了使 UI 可交互,需要能夠觸發底層數據模型的變化。 React 通過 state 使這變得簡單。

為了正確構建利用,首先需要斟酌利用需要的最小的可變 state 數據模型集合。此處關鍵點在于精簡:不要存儲重復的數據。構造出絕對最小的滿足利用需要的最小 state 是有必要的,并且計算出其它強烈需要的東西。

本案例較簡單,state很明顯是inputText,即input輸入框中的值。

而對1般情況,可以簡單地對每項數據提出3個問題:

  1. 是不是是從父級通過props傳入的?如果是,可能不是state。
  2. 是不是會隨著時間改變?如果不是,可能不是state。
  3. 能夠根據組件中其他的state數據或props計算出來嗎?如果是,就不是state。

第5步:確認state的生命周期

找出了state以后,需要繼續找出那些組件會被state更新,即哪些組件應當具有state數據模型,本案例一樣很簡單,由于輸入框input要判斷用戶輸入是不是符合正則表達式要求,因此與input相干的組件都應當具有state。依照第1種細分,InputBox組件應當具有state,依照第2個細分,由于只存在1個組件LimitedInputBox,故其應當具有state

//細分結構 var data = { labelText: "酒店地址", hinderText: "請填寫酒店地址", buttonImgSrc: "eliminate.png", regExp: /^\w{5,8}$/ }; var Title = React.creatClass({ render: function() { return ( <label>{this.props.labelText}</label> ); } }); var InputBox = React.createClass({ render: function() { return ( <input placeholder={this.props.hinderText} value={this.props.inputText} regExp={this.props.regExp}> </input> ); } }); var ClearButton = React.createClass({ render: function() { return ( <img src={this.props.buttonImgSrc}></> ); } }); var LimitedInputBox = React.createClass({ getInitialState: function() { return { inputText: '' }; }, render: function() { return ( <Title labelText={this.props.data.labelText} /> <InputBox hinderText={this.props.data.hinderText} inputText={this.state.inputText} regExp={this.props.data.regExp} /> <ClearButton buttonImgSrc={this.props.data.buttonImgSrc} /> ); } }); ReactDOM.render( <LimitedInputBox data={data} />, document.getElementById('example') );
/** author : river he**/ //粗劃分 var data = { labelText: "酒店地址", hinderText: "請填寫酒店地址", buttonImgSrc: "eliminate.png", regExp: /^\w{5,8}$/ }; var LimitedInputBox = React.createClass({ //初始化state getInitialState: function() { return { inputText: '' }; }, render: function() { return ( <div> <label >{this.props.data.labelText}</label> <input placeholder={this.props.data.hinderText} regExp={this.props.data.regExp} value={this.state.inputText} ></input> <img src={this.props.data.buttonImgSrc} </img> </div> ); } }); ReactDOM.render( <LimitedInputBox data={data} />, document.getElementById('example') );

第6步:添加反向數據流

前面構建了渲染正確的基于propsstate的沿著組件樹從上至下單項數據活動的利用。然后我們需要構建反向的數據活動方式:組件樹中層級很深的表單組件更新父級中的state

如果嘗試在前面的輸入框中輸入,React會疏忽你的輸入。這是成心的,由于已設置了inputvalue屬性,使其總是和LimitedInputBox(對粗分的情況,就是其本身)傳遞過來的state1致。

但是我們希望的是,不管用戶什么時候改變了表單,都要更新state來反利用戶的輸入。由于組件只能更新自己的stateLimitedInputBox將會傳遞1個回調函數給InputBox,此函數將會在state應當被改變時觸發。我們可使用inputonChange事件來監聽用戶輸入,從而肯定什么時候觸發回調函數。

LimitedInputBox傳遞的回調函數將會調用setState(),然后利用將會被更新。

/**author : River He*/ //細分結構 var data = { labelText: "酒店地址", hinderText: "請填寫酒店地址", buttonImgSrc: "eliminate.png", regExp: /^\w{5,8}$/ }; var Title = React.createClass({ render: function() { return ( <label>{this.props.labelText}</label> ); } }); var InputBox = React.createClass({ handleChange: function() { this.props.onUserInput( this.refs.inputBox.value ); }, fitRegExp: function(inputText) { if(inputText.match(this.props.regExp) != null) { // console.log("true"); return true; } else { // console.log("false"); return false; } }, render: function() { return ( <input style={this.fitRegExp(this.props.inputText)?({border: '1px solid green'}):({border: '1px solid red'})} placeholder={this.props.hinderText} value={this.props.inputText} regExp={this.props.regExp} ref="inputBox" onChange={this.handleChange}> </input> ); } }); var ClearButton = React.createClass({ handleClick: function() { this.props.onClear(); }, render: function() { return ( <img src={this.props.buttonImgSrc} onClick={this.handleClick} /> ); } }); var LimitedInputBox = React.createClass({ getInitialState: function() { return { inputText: '' }; }, handleUserInput: function(inputText) { this.setState({ inputText: inputText }); }, handleClear: function() { this.delText(); }, getText: function() { return this.state.inputText; }, setText: function(text) { this.setState({ inputText: text }); }, delText: function() { this.setState({ inputText: '' }); }, render: function() { return ( <div> <Title labelText={this.props.data.labelText} /> <InputBox hinderText={this.props.data.hinderText} inputText={this.state.inputText} regExp={this.props.data.regExp} onUserInput={this.handleUserInput} /> <ClearButton buttonImgSrc={this.props.data.buttonImgSrc} onClear={this.handleClear} /> </div> ); } }); ReactDOM.render( <LimitedInputBox data={data} />, document.getElementById('example') );
/** author : river he**/ //粗分結構 var data = { labelText: "酒店地址", hinderText: "請填寫酒店地址", regExp: /^\w{5,8}$/ }; var LimitedInputBox = React.createClass({ //初始化state getInitialState: function() { return { inputText: '' }; }, // handleKeyUp: function(inputText) { // this.setState({ // inputText: this.refs.input.value.trim() // }); // }, //處理輸入框變化 handleChange: function() { this.setState({ inputText: this.refs.input.value.trim() }); }, //處理刪除事件 handleClear: function() { this.delText(); }, //刪除方法 delText: function() { // console.log(this.refs.input.text); this.setState({ inputText: '' }); }, //獲得用戶輸入 getText: function() { return this.state.inputText; }, //設置輸入框內容 setText: function(text) { this.setState({ inputText: text.trim() }); }, //判斷輸入內容否符合設置的正則表達式 fitRegExp: function(inputText) { // console.log("start fitRegExp"); if(inputText.match(this.props.data.regExp) != null) { // console.log("true"); return true; } else { // console.log("false"); return false; } }, render: function() { return ( <div> <label >{this.props.data.labelText}</label> <input style={this.fitRegExp(this.state.inputText)? ({border: '1px solid green'}):({border: '1px solid red'})} placeholder={this.props.data.hinderText} regExp={this.props.data.regExp} // onKeyUp={this.handleKeyUp} onChange={this.handleChange} value={this.state.inputText} ref='input' ></input> <img src="eliminate.png" onClick={this.handleClear}></img> </div> ); } }); ReactDOM.render( <LimitedInputBox data={data} />, document.getElementById('example') );

以上就是1個簡單的輸入框組件,相應的html模板和css以下,沒有甚么樣式,希望讀者體諒,有時間改下css。

<!-- limitedInputBox.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF⑻"> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> <!-- <script type="text/babel" src="http://www.jyygyx.com/upload/caiji/20160629/limitedInputBox.js"></script> --> <script src="inputWidget.js" type="text/babel"></script> <link rel="stylesheet" href="limitedInputBox.css"> <title>LimitedInputBox</title> </head> <body> <div id="example"></div> </body> </html>
//limitedInputBox.css img { height: 14px; width: 14px; }

JS Bin on jsbin.com

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 免费黄色在线看 | 亚洲精品九九 | 美玉足脚交一区二区三区图片 | 欧美乱大交做爰xxxⅹ性3 | 亚洲性视频网站 | 99亚洲精品 | 欧美91 | 麻豆免费在线 | 亚洲成人久久久 | 一级毛片在线播放 | 91精品国产综合久久福利软件 | 欧美一区二区三区喷汁尤物 | 亚洲视频二区 | 国产精品射 | 日韩毛片在线观看 | 99精品国产高清一区二区麻豆 | 久久中文网 | 国产精品一区二区久久久久 | 在线观看国产 | 91高清免费看 | 午夜视频在线免费 | 日韩av一区二区在线观看 | 亚洲最大av网 | 久久国| 美女福利视频导航 | 91成人在线播放 | 国产精品久久久久毛片软件 | 成人免费视频播放 | 久久精品国产亚洲一区二区三区 | 这里只有精品久久 | 亚洲黄色影院 | 91精品久久久久久久99蜜桃 | 一区二区三区四区在线播放 | 国产精品视频专区 | 国产一区 | www.狠狠撸.com | 中文久久 | 亚洲精品二三区 | 欧美性受| 在线观看国产 | 午夜激情视频在线 |