部分《React 数据流管理:组件之间数据是如何传递的?》,我们使用Props来完成React数据流管理所有内容的学习。至于前面提到的JSX交互部分,用户的页面操作都是由表单来承担的,所以接下来表单的处理是重点。React中对表单的处理其实就是用户和应用的交互逻辑,而应用和用户的交互是由表单来承担的,所以我们真正学习的是JSX和用户表单数据的交互。在React中,表单分为两类:受控表单和非受控表单。受控表单:表单元素的值全部由React管理。此时表单元素中的值都放在state中,所以需要从state中获取表单元素中的值。不受控形式:不受React管理控制。表单元素的数据由DOM元素自己管理。表单元素的值也保存在DOM元素中,获取时需要对DOM元素进行操作。React的基本逻辑是数据决定UI,所以React必须控制数据,不受控制的表单显然不符合这个基本逻辑,在实际开发中也很少遇到。重点是受控形式。接下来,我们通过具体的代码进行学习研究。受控组件(表单)我们使用普通的表单,将状态中的数据显示在表单中:importReact,{Component}from'react'exportclassTablesextendsComponent{state={name:"xiling"}render(){return(
)}}exportdefaultTables页面中呈现的表单和内容是完全没问题的,但是当我们尝试修改页面中的表单数据时,你会发现修改不了,报错。这和前面学习到的状态的修改条件是一致的,不能直接修改。它需要通过setState()方法修改数据。代码如下:changes=(ev)=>{this.setState({name:ev.target.value})}render(){return(
)}}表单被用户修改为输入操作,即用户在表单中输入什么值,对应的状态变为什么值.而这个操作需要获取用户在表单中的输入。同时,我们还需要知道用户什么时候触发了修改动作。因此,我们需要为表单修改值的动作绑定一个触发事件onChange。事件触发后,事件处理函数接收事件对象(ev)获取用户修改的内容,然后通过setState()修改数据。这个逻辑没有错,但是如果我们有两个表单,我们需要两个对应的事件处理器,如果有3个表单,4个表单,10个表单...importReact,{Component}from'react'exportclassTablesextendsComponent{state={name:"xiling",age:18}changes=(ev)=>{this.setState({name:ev.target.value})}ages=(ev)=>{this.setState({age:ev.target.value})}render(){return(
)}}exportdefaultTables肯定是错误的,最直观的修改方式就是去掉单独的事件处理函数,直接把事件函数处理写在上面事件绑定,例如:render(){return(
{this.setState({name:ev.target.值})}}/>{this.setState({age:ev.target.value})}}/>
)}不过,即便如此,还是有必要分别为每个表单编写和修改逻辑。一旦表格多了,也是一个很棘手的问题。表单的修改能否统一管理?当然!我们可以使用form属性来实现。方法也很简单。我们给每个表单添加一个name属性,属性值和状态中的属性值一致,这样在事件处理函数中就可以获取到表单的属性值。因为和state是一致的,所以我们可以直接使用form属性作为要修改的state属性的值。代码如下:importReact,{Component}from'react'exportclassTablesextendsComponent{state={name:"xiling",age:18}tables=(ev)=>{constprop=ev.target.namethis.setState({[prop]:ev.target.value})}render(){return(
this.tables(ev)}/>
)}}exportdefaultTables最后我们来解决错误报告问题。报错的原因在控制台已经很清楚了:被控制的表单需要相应的事件处理来控制数据。更改,否则会报错。但是,如果我只想显示窗体中的数据,不想修改控件,还是会出现这样的错误,非常不友好。我应该怎么办?有两种解决方案,两者都很简单。我们看一下:render(){return(
{/*首先是添加一个readOnly属性,告诉React这个表单是只读的,不需要修改*/>{this.setState({name:ev.target.value})}}/>{/*需要注意的是设置为read后-only,即使添加了修改事件,也不会无法修改*/}{/*第二种是使用defaultValue赋值*/}{/*表示设置默认值*/>
)}下篇将举例说明常用的受控形式和非受控形式的原始规范写法。再写一个React语法的入门案例,我会很体面地结束这个系列,Arigado!