react入门——实现一个输入框组件

react入门——实现一个输入框组件,第1张

概述React组件化开发初试按照官方文档和例程博客,实现了一个简单的输入框组件。如果想了解官方案例,请参考深入理解 React总结一下,一个简单的React.js应用应按照以下步骤构建:设计组件原型和JSON API;拆分用户界面为一个组件树;利用React, 创建应用的一个静态版本;识别出最小的(但是 React组件化开发初试

依照官方文档和例程博客,实现了1个简单的输入框组件。

如果想了解官方案例,请参考深入理解 React

总结1下,1个简单的React.Js利用应依照以下步骤构建:

设计组件原型和JsON API;拆分用户界面为1个组件树;利用React, 创建利用的1个静态版本;辨认出最小的(但是完全的)代表UI的state;确认state的生命周期;添加反向数据流。

个人认为这里的难点在于如何拆分用户界面,粒度过大不利于组件化的重用,粒度太小的话,显得冗余过量,并且复杂度陡升。本人最开始尝试细化的拆分,尽可能让1个组件只完成1个很小的功能需求,但最后反而不知道如何给每一个组件分配其任务。

另外一个难点来源于对state的判断,其实如果能够辨认出最小的state,读者会发现1个复杂的组件所需的state数量其实很少。

在React.Js中,有两种数据模型,state代表的是会动态变化的状态,props代表的是父级传递而来的属性,state会反过来更新UI,而props只是1次性设置填充。

第1步:构建原型

我们的组件要完成以下功能:

可以定制label和输入框的placeholder的内容可以有个属性设置个正则,输入的文字不符合正则的时候输入框就标红右边的大叉icon点击后,消失并清楚输入框内容组件需要开放3个对外方法,获得(获得值时trim),设置(设置值时trim),删除,输入框的内容。

原型比较简单,样式以下:

JsON接口数据以下:

{ labelText: "酒店地址",hinderText: "请填写酒店地址",buttonimgSrc:regExp: /^\w{5,8}$/}

我们通过JsON数据设置输入框组件的label标签、input的placeholder属性和对用户输入的正则验证。

第2步:拆分用户界面为1个组件树

在完成用户界面切分的进程中,最开始,如图原型图所示,做了非常细粒度的拆分,拆分结构以下:

limitedinputBox
TitleinputBoxClearbutton

这里,将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**///细分结构@H_502_144@var data = { labelText: "酒店地址",hinderText: "请填写酒店地址",buttonimgSrc: "eliminate.png",regExp: /^\w{5,8}$/};@H_502_144@var Title = React.creatClass({ render: @H_502_144@function() { @H_502_144@return ( <label>{@H_502_144@this.props.labelText}</label> ); }});@H_502_144@var inputBox = React.createClass({ render: @H_502_144@function() { @H_502_144@return ( <input placeholder={@H_502_144@this.props.hinderText} regExp={@H_502_144@this.props.regExp}> </input> ); }});@H_502_144@var Clearbutton = React.createClass({ render: @H_502_144@function() { @H_502_144@return ( <img src={@H_502_144@this.props.buttonimgSrc}></> ); }});@H_502_144@var limitedinputBox = React.createClass({ render: @H_502_144@function() { @H_502_144@return ( <Title labelText={@H_502_144@this.props.data.labelText} /> <inputBox hinderText={@H_502_144@this.props.data.hinderText} regExp={@H_502_144@this.props.data.regExp} /> <Clearbutton buttonimgSrc={@H_502_144@this.props.data.buttonimgSrc} /> ); }});ReactDOM.render( <limitedinputBox data={data} />,document.getElementByID('example'));/** author : river he**///粗划分@H_502_144@var data = { labelText: "酒店地址",8}$/};@H_502_144@var limitedinputBox = React.createClass({ render: function() { @H_502_144@return ( <div> <label >{@H_502_144@this.props.data.labelText}</label> <input placeholder={@H_502_144@this.props.data.hinderText} regExp={@H_502_144@this.props.data.regExp}> </input> <img src={@H_502_144@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个问题:

是不是是从父级通过props传入的?如果是,可能不是state。 是不是会随着时间改变?如果不是,可能不是state。 能够根据组件中其他的state数据或props计算出来吗?如果是,就不是state。
第5步:确认state的生命周期

找出了state以后,需要继续找出那些组件会被state更新,即哪些组件应当具有state数据模型,本案例一样很简单,由于输入框input要判断用户输入是不是符合正则表达式要求,因此与input相干的组件都应当具有state。依照第1种细分,inputBox组件应当具有state,依照第2个细分,由于只存在1个组件limitedinputBox,故其应当具有state

//细分结构@H_502_144@var data = { labelText: "酒店地址",8}$/};@H_502_144@var Title = React.creatClass({ render: @H_502_144@function() { @H_502_144@return ( <label>{@H_502_144@this.props.labelText}</label> ); }});@H_502_144@var inputBox = React.createClass({ render: @H_502_144@function() { @H_502_144@return ( <input placeholder={@H_502_144@this.props.hinderText} value={@H_502_144@this.props.inputText} regExp={@H_502_144@this.props.regExp}> </input> ); }});@H_502_144@var Clearbutton = React.createClass({ render: @H_502_144@function() { @H_502_144@return ( <img src={@H_502_144@this.props.buttonimgSrc}></> ); }});@H_502_144@var limitedinputBox = React.createClass({ getinitialState: @H_502_144@function() { @H_502_144@return { inputText: '' }; },render: @H_502_144@function() { @H_502_144@return ( <Title labelText={@H_502_144@this.props.data.labelText} /> <inputBox hinderText={@H_502_144@this.props.data.hinderText} inputText={@H_502_144@this.state.inputText} regExp={@H_502_144@this.props.data.regExp} /> <Clearbutton buttonimgSrc={@H_502_144@this.props.data.buttonimgSrc} /> ); }});ReactDOM.render( <limitedinputBox data={data} />,8}$/};@H_502_144@var limitedinputBox = React.createClass({ //初始化state getinitialState: function() { @H_502_144@return { inputText: '' }; },render: function() { @H_502_144@return ( <div> <label >{@H_502_144@this.props.data.labelText}</label> <input placeholder={@H_502_144@this.props.data.hinderText} regExp={@H_502_144@this.props.data.regExp} value={@H_502_144@this.state.inputText} ></input> <img src={@H_502_144@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*///细分结构@H_502_144@var data = { labelText: "酒店地址",8}$/};@H_502_144@var Title = React.createClass({ render: @H_502_144@function() { @H_502_144@return ( <label>{@H_502_144@this.props.labelText}</label> ); }});@H_502_144@var inputBox = React.createClass({ handleChange: @H_502_144@function() { @H_502_144@this.props.onUserinput( @H_502_144@this.refs.inputBox.value ); },fitRegExp: @H_502_144@function(inputText) { @H_502_144@if(inputText.match(@H_502_144@this.props.regExp) != null) { // console.log("true"); @H_502_144@return true; } @H_502_144@else { // console.log("false"); @H_502_144@return false; } },render: @H_502_144@function() { @H_502_144@return ( <input style={@H_502_144@this.fitRegExp(@H_502_144@this.props.inputText)?({border: '1px solID green'}):({border: '1px solID red'})} placeholder={@H_502_144@this.props.hinderText} value={@H_502_144@this.props.inputText} regExp={@H_502_144@this.props.regExp} ref="inputBox" onChange={@H_502_144@this.handleChange}> </input> ); }});@H_502_144@var Clearbutton = React.createClass({ handleClick: @H_502_144@function() { @H_502_144@this.props.onClear(); },render: @H_502_144@function() { @H_502_144@return ( <img src={@H_502_144@this.props.buttonimgSrc} onClick={@H_502_144@this.handleClick} /> ); }});@H_502_144@var limitedinputBox = React.createClass({ getinitialState: @H_502_144@function() { @H_502_144@return { inputText: '' }; },handleUserinput: @H_502_144@function(inputText) { @H_502_144@this.setState({ inputText: inputText }); },handleClear: @H_502_144@function() { @H_502_144@this.delText(); },getText: @H_502_144@function() { @H_502_144@return @H_502_144@this.state.inputText; },setText: @H_502_144@function(text) { @H_502_144@this.setState({ inputText: text }); },delText: @H_502_144@function() { @H_502_144@this.setState({ inputText: '' }); },render: @H_502_144@function() { @H_502_144@return ( <div> <Title labelText={@H_502_144@this.props.data.labelText} /> <inputBox hinderText={@H_502_144@this.props.data.hinderText} inputText={@H_502_144@this.state.inputText} regExp={@H_502_144@this.props.data.regExp} onUserinput={@H_502_144@this.handleUserinput} /> <Clearbutton buttonimgSrc={@H_502_144@this.props.data.buttonimgSrc} onClear={@H_502_144@this.handleClear} /> </div> ); }});ReactDOM.render( <limitedinputBox data={data} />,document.getElementByID('example'));/** author : river he**///粗分结构@H_502_144@var data = { labelText: "酒店地址",8}$/};@H_502_144@var limitedinputBox = React.createClass({ //初始化state getinitialState: @H_502_144@function() { @H_502_144@return { inputText: '' }; },// handleKeyUp: function(inputText) { // this.setState({ // inputText: this.refs.input.value.trim() // }); // }, //处理输入框变化 handleChange: @H_502_144@function() { @H_502_144@this.setState({ inputText: @H_502_144@this.refs.input.value.trim() }); },//处理删除事件 handleClear: @H_502_144@function() { @H_502_144@this.delText(); },//删除方法 delText: @H_502_144@function() { // console.log(this.refs.input.text); @H_502_144@this.setState({ inputText: '' }); },//获得用户输入 getText: @H_502_144@function() { @H_502_144@return @H_502_144@this.state.inputText; },//设置输入框内容 setText: @H_502_144@function(text) { @H_502_144@this.setState({ inputText: text.trim() }); },//判断输入内容否符合设置的正则表达式 fitRegExp: @H_502_144@function(inputText) { // console.log("start fitRegExp"); @H_502_144@if(inputText.match(@H_502_144@this.props.data.regExp) != null) { // console.log("true"); @H_502_144@return true; } @H_502_144@else { // console.log("false"); @H_502_144@return false; } },render: @H_502_144@function() { @H_502_144@return ( <div> <label >{@H_502_144@this.props.data.labelText}</label> <input style={@H_502_144@this.fitRegExp(@H_502_144@this.state.inputText)? ({border: '1px solID green'}):({border: '1px solID red'})} placeholder={@H_502_144@this.props.data.hinderText} regExp={@H_502_144@this.props.data.regExp} // onKeyUp={this.handleKeyUp} onChange={@H_502_144@this.handleChange} value={@H_502_144@this.state.inputText} ref='input' ></input> <img src="eliminate.png" onClick={@H_502_144@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.wfuyu.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.CSSimg { height: 14px; wIDth: 14px;}

Js Bin on Jsbin.com

总结

以上是内存溢出为你收集整理的react入门——实现一个输入框组件全部内容,希望文章能够帮你解决react入门——实现一个输入框组件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1016111.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存