React-引领未来的用户界面开发框架-读书笔记(三)
第8章 DOM操作多数情况下,React的虚拟DOM足以用来创建你想要的用户体验,而根本不需要直接操作底层真实的DOM。然而也有一些例外。最常见的场景包括:需要与一个没有使用React的第三方类库进行整合,或者执行一个React没有原生支持的操作。 访问受控的DOM节点想要访问React控制的DOM节点,首先必须能够访问到负责这些DOM的组件。这可以通过为子组件添加一个ref属性来实现。 render () {
return (
<canvas ref="mainCanvas" />
)
}
这样就可以通过 ??必须保证赋给每个子组件的ref值在所有子组件中是唯一的;否则操作就会失效。 可以通过getDOMNode()方法访问到底层的DOM节点。 ??不可以在render方法中这样做。因为这时底层的DOM可能不是最新的(甚至尚未创建) 尽管refs和getDOMNode很强大,但请在没有其他的方法能够实现你需要的功能时再去选择它们。使用它们会成为React在性能优化上的障碍,并且增加应用的复杂性。 componentDidMount方法只会为每个DOM节点调用一次。 如果在componentDidMount方法内导致了DOM节点无法被移除,有可能导致内存泄漏或者其他的问题。如果你担心这一点,请在componentWillUnmount监听器,用于在组件的DOM节点移除时清理它自身。 第9章 表单在React中,表单组件有两种类型:约束组件和无约束组件 无约束组件 给定一个HTML的 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="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=:</label>
文本框和Select React对 //非约束的
<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的 //非约束的
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="A" checked={this.state.checked} onChange={this.handleChange} />
<br/>
<button type="submit">speak</button>
</form>
);
}
});
在这两个例子中, 表单元素的name属性在React中,name属性对于表单元素来说并没有那么重要。因为约束表单组件已经把值存储到了state中,并且表单的提交事件也会被拦截。在获取表单值的时候,name属性并不是必需的。对于非约束的表单组件来说,也可以使用refs来直接访问表单元素。虽然如此,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 FocusReact实现了autoFocus属性,因此在组件第一次被挂载时,如果没有其他的表单聚焦时React就会把焦点放到这个组件对应的表单域中,例如: <input type="given_name"autoFocus="true" />
还有一种方法就是调用DOMNode的focus方法,手动设置表单域聚焦。 可用性React虽然提高了开发者的生产力,但是也有不尽如人意的地方,使用React编写的组件常常缺乏可用性,例如表单提交无法通过键盘敲击回车键来实现,而这明明是HTML表单默认的提交方式。 要编写具有高可用性的好组件其实也不难,只是编写组件时需要花时间进行更多的思考。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |