第8章 DOM操作

多数情况下,React的虚拟DOM足以用来创建你想要的用户体验,而根本不需要直接操作底层真实的DOM。然而也有一些例外。最常见的场景包括:需要与一个没有使用React的第三方类库进行整合,或者执行一个React没有原生支持的操作。

访问受控的DOM节点

想要访问React控制的DOM节点,首先必须能够访问到负责这些DOM的组件。这可以通过为子组件添加一个ref属性来实现。

render () {return (<canvas ref="mainCanvas" />)
}

这样就可以通过this.refs.mainCanvas访问到<canvas组件。

⚠️必须保证赋给每个子组件的ref值在所有子组件中是唯一的;否则操作就会失效。

可以通过getDOMNode()方法访问到底层的DOM节点。

⚠️不可以在render方法中这样做。因为这时底层的DOM可能不是最新的(甚至尚未创建)

尽管refs和getDOMNode很强大,但请在没有其他的方法能够实现你需要的功能时再去选择它们。使用它们会成为React在性能优化上的障碍,并且增加应用的复杂性。

componentDidMount方法只会为每个DOM节点调用一次。

如果在componentDidMount方法内导致了DOM节点无法被移除,有可能导致内存泄漏或者其他的问题。如果你担心这一点,请在componentWillUnmount监听器,用于在组件的DOM节点移除时清理它自身。

第9章 表单

在React中,表单组件有两种类型:约束组件和无约束组件

无约束组件

给定一个HTML的<input/>一个值,它的值是可以改变的。这正是无约束组件名称的由来,因为表单组件的值是不受React控制的。

submitHandler = (event) => {event.preventDefault();var hellTo = this.refs.hellTo.getDOMNode().value;alert(hellTo)
}
render () {return (<form onSubmit={this.submitHandler}><input ref="hellTo" type="text" defaultValue="Hello World!" /><button type="submit">Speak</button></form>)
}

无约束组件可以用在基本的无需任何验证或者输入控制的表单中。

约束组件

约束组件,表单的状态交由React组件控制,状态值被存储在React组件的state中。

constructor(props) {super(props);this.state = {helloTo = 'Hello World!'}
}
handleChange = (event) => {this.setState({helloTo: event.target.value})
}
submitHandler = (event) => {event.preventDefault();alert(this.state.helloTo)
}
render () {return (<form onSubmit={this.submitHandler}><input ref="hellTo" type="text" onChange={this.handleChange} /><button type="submit">Speak</button></form>)
}

表单事件

React支持所有HTML事件。这些事件遵循驼峰命名的约定,且会被转成合成事件。

所有合成事件都提供了event.target来访问触发事件的DOM节点。

Label

由于for是JavaScript的保留字,所以我们无法把它作为一个对象的属性。

jsx

<label htmlFor="name">Name:</label>

javascript

React.DOM.label({htmlFor:"name", "Name"});

渲染后:

<label for="name">Name:</label>

文本框和Select

React对<textarea/><select/>的接口做了一些修改,提升了一致性,让它们操作起来更容易。

<textarea/>被改的更像<input/>了,允许我们设置value和defaulteValue。

//非约束的
<textareadefaultValue ="HelloWorld" />
//约束的
<textareavalue={this.state.helloTo } onChange ={this.handleChange} />//非约束的
<selectdefaultValue="8"><option value="A">First Option</option><option value="B">Second Option</option><option value= "C">Third Option</option>
</select>
//约束的
<selectvalue ={this.state.helloTo} onchange={this.handleChange}><option value="A">FirstOption </option><option value="B">Second Option </option><option value="C">Third Option</option>
</select>

React支持都选selce他,需要给value的defauletValue传递一个数组,如:defaultValue={["A","B"]}。

当使用可多选的select时,select组件的值在选项被选择时不会更新,只有选项的selected属性会发生变化。你可以使用ref或者syntheticEvent.target来访问选项,检查他们是否被选中。

下面的例子中,handleChange循环检查DOM,并过滤出哪些选项被选中了。

class Hello extends React.Component {constructor(props) {super(props);this.state = {option: ["B"]};}
    handleChange = (event) => {var checked = [];var sel = event.target;for (var i = 0; i < sel.length; i++){var option = sel.options[i];if (option.selected){checked.push(option.value);}}this.setState({option: checked});}
    submitHandler = (event) => {event.preventDefault();alert(this.state.options);}render () {return(<form onSubmit={this.submitHandler}><select multiple="true" value={this.state.options}onChange={this.handleChange}><option value="A">1</option><option value="B">2</option><option value="C">3</option></select><br /><button type="submit">speak</button></form>);}
}

复选框和单选框

复选框和单选框使用的则是完全不同的控制方式。

在HTML中,类似为checkbox或者radio的<input/>的行为完全不一样,通常,复选框或者单选框的值是不变的,只有checked的状态会变化,要控制复选框或者单选框,就要控制他们的checked属性,你要可以在非约束的复选框或者单选框中使用defaultChecked。

//非约束的
var MyForm = React.createClass({submitHandler: function(event){event.preventDefault();alert(this.refs.checked.getDOMNode().checked);},render: function(){return (<form onSubmit={this.submitHandler}><input ref="checked" type="checkbox" value="A" defaultChecked="true" /><br /><button type="submit">speak</button></form>);}
});//约束的
var MyForm = React.createClass({getInitialState: function(){return {checked: true};},handleChange: function(event){this.setState({checked: event.target.checked});},submitHandler: function(event){event.preventDefault();alert(this.state.checked);},render: function(){return (<form onSubmit={this.submitHandler}><input type="checkbox" value="A" checked={this.state.checked} onChange={this.handleChange} /><br/><button type="submit">speak</button></form>);}
});

在这两个例子中,<input/>的值一直都是A,只有checked的状态在变化。

表单元素的name属性

在React中,name属性对于表单元素来说并没有那么重要。因为约束表单组件已经把值存储到了state中,并且表单的提交事件也会被拦截。在获取表单值的时候,name属性并不是必需的。对于非约束的表单组件来说,也可以使用refs来直接访问表单元素。虽然如此,name仍然是表单组件中非常重要的一部分。

  • name属性可以让第三方表单序列化类库在React中正常工作。
  • 对于任然使用传统提交方式的表单来说,name属性是必需的。
  • 在用户的浏览器中,name被用在自动填写常用信息中,比如用户地址等。
  • 对于非约束的单选框组件来讲,name是有必要得,它可作为这些组件分组的依据。确保在同一时刻,同一表单中拥有同样name的单选框只有一个可以被选中。如果不使用name属性,这一行为可以使用约束的单选框实现。

多表单与change处理器

在使用约束的表单组件时,没有愿意重复地为每一个组件编写change处理器。可以在React中重用一个事件处理器。

可以有两种方式:通过.bind传递其他参数;使用DOMNode的name属性来判断需要更新哪个组件的状态。

示例可以看page75~77

除此之外,React还在addon中提供了一个mixin,React.addons.LinkedStateMixin,通过另一种方式解决同样的问题。

React.addons.LinkedStateMixin为组件提供了一个linkState方法。linkState返回一个对象,包含value和requestChange两个属性。

value根据提供的name属性从state中获取对应的值。

requestChange是一个函数,使用心得值更新同名的state。

mixins:[React.addons.LinkedStateMixin]

submitHandler = (event) => {event.preventDefault();alert(this.state.family_name);
}<input type="text" name="family_name" valueLink={this.linkState('family_name')} />

这种方法便于控制表单域,把其值保存在福组件的state中。而且,其数据流仍然与其他约束的表单元素保持一致。

但是,使用这种方式往数据流中添加定制功能时,复杂度会增加。我们建议只在特性的场景下使用。因为传统的约束表单组件提供了同样的功能而且更加灵活。

自定义表单组件

当编写自定义组件时,接口应当与其他表单组件保持一致。这可以帮助用户理解代码,明白如何使用自定义组件,且无须深入到组件的实现细节里。

示例:page79~82

Focus

React实现了autoFocus属性,因此在组件第一次被挂载时,如果没有其他的表单聚焦时React就会把焦点放到这个组件对应的表单域中,例如:

<input type="text" name="given_name"autoFocus="true" />

还有一种方法就是调用DOMNode的focus方法,手动设置表单域聚焦。

可用性

React虽然提高了开发者的生产力,但是也有不尽如人意的地方,使用React编写的组件常常缺乏可用性,例如表单提交无法通过键盘敲击回车键来实现,而这明明是HTML表单默认的提交方式。

要编写具有高可用性的好组件其实也不难,只是编写组件时需要花时间进行更多的思考。

  • 把要求传达清楚
  • 不断地反馈
  • 迅速响应
  • 符合用户的预期
  • 可访问
  • 减少用户的输入

React-引领未来的用户界面开发框架-读书笔记(三)相关推荐

  1. React-引领未来的用户界面开发框架-读书笔记(一)

    这本书的主要内容都是以react v0.12为主,ES5语法,笔记中将会使用react v0.14和RS6. 第1章 react简介 1.本质上是一个状态机,它以精简的模型管理复杂的随着时间而变化的状 ...

  2. 读书笔记《React引领未来的用户界面开发框架》

    入门react,感觉这本书只是简单说了一些相关概念知识,并没有很详尽地展开论述,看了,做个总结笔记.

  3. React-引领未来的用户界面开发框架-读书笔记(五)

    第11章 性能优化 Reactde Dom diff算法使我们能够在任意时间点高效地重新绘制整个用户界面,并保证最小程度的DOM改变,然而,也存在需要对组件进行细致优化的情况,这时就需要渲染一个新的D ...

  4. React-引领未来的用户界面开发框架-读书笔记(二)

    第4章 数据流 由于react的数据流向是单向的(其父节点传递到子节点), 因此组件是简单且易于把握的(它们只需要从父节点获取props渲染即可) 假如顶层组件的某个prop改变了,react会递归地 ...

  5. React-引领未来的用户界面开发框架-读书笔记(八)

    第16章 架构模式 React主要功能在于渲染HTML.可以将其看成是MVC中的V,它不会影响到组件中直接调用AJAX请求之类的操作: var TakeSurvey=React.CreateClass ...

  6. React-引领未来的用户界面开发框架-读书笔记(七)

    第14章 开发工具 React使用了若干的抽象层来帮助你更轻松地开发组件.推导程序状态.然而,在调试.构建及分发应用时,这样设计就会产生负面影响了. 幸运的是,我们拥有一些非常好的开发工具能在开发及构 ...

  7. React-引领未来的用户界面开发框架-读书笔记(六)

    第12章 服务端渲染 想让搜索引擎抓取到你的站点,服务端渲染这一步不可或缺,服务端渲染还可以提升站点的性能,因为在加载JavaScript脚本的同时,浏览器就可以进行页面渲染. React的虚拟DOM ...

  8. React-引领未来的用户界面开发框架-读书笔记(四)

    第10章 动画 动画可以让用户体验变得更加流畅自然,而React的TransitionGroup插件配合CSS3可以让我们在项目中整合动画效果的变得易如反掌. 通常情况下,浏览器中的动画都拥有一套极其 ...

  9. 读书笔记《React:引领未来的用户界面开发框架》

    <React:引领未来的用户界面开发框架>(GitHub 附demo版) 1.Component的创建与复合 1.1 React简介 背景介绍,全书概览 1.本质上是一个状态机,它以精简的 ...

最新文章

  1. “钱”在这个社会是怎么一个地位
  2. HDU 4391 Paint The Wall 段树(水
  3. PKI/CA (4)根CA信任模型“概述”
  4. 计算机excel行高在哪里,如何在Excel2016中设置改行高和列宽?
  5. C#构造函数、操作符重载以及自定义类型转换
  6. zookeeper 可视化_大厂,常用,四款,大屏可视化工具
  7. 苹果暗黑模式_【蜜茶原创】微信最终妥协苹果,暗黑模式正式上线!
  8. linux 命令详解 十六
  9. 再见2G网络!中国联通开始全面退网
  10. resultSet.next() 位置处报错:java.lang.OutOfMemoryError: Java heap space
  11. python选取tensor某一维_Python按维数操作多维张量,Pytorch,对,Tensor,维度
  12. 时间序列的分析和预测ARIMA
  13. 基于PyQt5实现保存网页为pdf
  14. 微信小程序学习14--小程序微信支付流程分析及实现
  15. 今天很悲剧,心情很郁闷
  16. Excel.Application手册
  17. 解决python3+selenium+chromedriver运行时chrome浏览器闪退问题
  18. c语言背景音乐,背景图,背景字体
  19. golang GPM模型理解
  20. 什么叫爬虫python_网络爬虫是什么?

热门文章

  1. 网络工程师要如何选择?
  2. 黄老师离开呆了十年的上海
  3. 使用 ML.NET 进行保险价格预测
  4. 一句 Task.Result 就死锁, 这代码还怎么写?
  5. 使用工作单元UnitOfWork实现事务
  6. 理解C#泛型运作原理
  7. 初识ABP vNext(12):模块的独立运行与托管
  8. 跟我一起学.NetCore之路由的最佳实现
  9. 进击吧!Blazor!第一期回顾
  10. 常见的C#异常及其修复方法