多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

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

react入門——實現(xiàn)一個輸入框組件

來源:程序員人生   發(fā)布時間:2016-07-11 12:52:18 閱讀次數(shù):6564次

React組件化開發(fā)初試

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

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

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

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

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

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

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

第1步:構建原型

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

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

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

JSON接口數(shù)據(jù)以下:

{ labelText: "酒店地址", hinderText: "請?zhí)顚懢频甑刂?, buttonImgSrc: regExp: /^\w{5,8}$/ }

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

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

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

  • LimitedInputBox
    • Title
    • InputBox
    • ClearButton

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

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

  • LimitedInputBox

第3步:利用React, 創(chuàng)建利用的1個靜態(tài)版本

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

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

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

本例中,的props就是第1步構建的JSON數(shù)據(jù)。

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

/** author : River He**/ //細分結構 var data = { labelText: "酒店地址", hinderText: "請?zhí)顚懢频甑刂?, 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: "請?zhí)顚懢频甑刂?, 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 可交互,需要能夠觸發(fā)底層數(shù)據(jù)模型的變化。 React 通過 state 使這變得簡單。

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

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

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

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

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

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

//細分結構 var data = { labelText: "酒店地址", hinderText: "請?zhí)顚懢频甑刂?, 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: "請?zhí)顚懢频甑刂?, 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步:添加反向數(shù)據(jù)流

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

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

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

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

/**author : River He*/ //細分結構 var data = { labelText: "酒店地址", hinderText: "請?zhí)顚懢频甑刂?, 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: "請?zhí)顚懢频甑刂?, 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.vxbq.cn/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

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精品人成人免费国产 | 日本国产一区在线观看 | 久久男女 | 精品一区二区三区在线观看l | a天堂影院 | 日本动漫免费在线观看 | 国产亚洲小视频 | 亚洲精品国产专区一区 | 国产精品自在线 | 欧美国产一区二区三区 | 国产永久在线视频 | 欧美性生活视频免费播放网址大全观看 | 亚洲福利 | 亚洲日产2021三区在线 | 欧美一级性 | 青青草原在线视频免费观看 | 天堂在线www | 国产日韩欧美综合一区二区三区 | 日本欧美一区二区三区视频 | 欧美一级日韩一级亚洲一级 | 最近中文字幕免费高清mv | 精品一区二区三区视频在线观看免 | 波多野结衣资源在线观看 | 国产美女福利在线 | 亚洲精品一区二区乱码在线观看 | 国产suv精品 | 日本不卡高清中文字幕免费 | 欧美精品福利视频 | 视频在线观看网站免费 | 午夜色视频 | www.日本一区二区 | 爽爽免费视频 | 成人在线不卡视频 | 国产精品香蕉在线观看不卡 | 成人精品在线视频 | 欧美性乱 | 亚洲第一天堂无码专区 | 久久天天躁夜夜躁狠狠85台湾 | 中文字幕乱码中文乱码51精品 | 久久精品国产亚洲精品 | 精品久久久久久午夜 |