13.项目里用到了websocket推送,使用sockjs库把ws协议封装为http协议方便使用,stomp.js进行通信。 每推送一次刷新一次state。
实测发现: E5-2670 cpu, 16g内存, chrome 60.0.3112.113(正式版本) (64 位), 推送的极限间隔为13 ms。12ms时就会卡死chrome页面, 停止推送后待react计算完才会恢复,显示最新界面。
一开始时是15ms, 通过去除console.log,降低至13ms。
12.react 会通过dom diff算法刷新变化的dom。 深入浅出React(四):虚拟DOM Diff算法解析
因为diff算法逐层进行节点比较的特点,我们有时可以通过CSS隐藏或显示某些节点,而不是真的移除或添加DOM节点。
11. import {Component} from 'react';
这是es6规范中关于模块的用法,JavaScript ES6中export及export default的区别 (为了兼容 export了一个名字为default的变量,同export {New as default})
CommonJS 模块是对象,输入时必须查找对象属性。ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。
那么import,export在“编译时加载“是怎么实现的呢?(我是因为作用域的问题在纠结)
深入浅出ES6(十六):模块 Modules http://www.infoq.com/cn/articles/es6-in-depth-modules
10. Autobinding
In React components declared as ES6 classes, methods follow the same semantics as regular ES6 classes. This means that they don't automatically bind this
to the instance. You'll have to explicitly use .bind(this)
in the constructor.
我这里有个疑惑,为什么es6中不自动bind this呢? 这里答的很好 https://blog.andrewray.me/react-es6-autobinding-and-createclass/
Javascript functions are said to be "first class," meaning you can pass them around like any other data type. When we store a reference to sayHello
, we lose the relationship to obj
. We're invoking it as a function, not as a method.
回到react中的写法:
constructor中 this.method = this.method.bind(this);
render中 return (<div><input onClick={this.method}></input></div>)
JSX实际上会调用React.createClass(), onClick={this.method}可以理解为 inputDom.onclick = this.method;
自己写的类的对象 和 render生成的ReactDom对象 之间发生了function的传递,上下文(this)会变,所以需要bind绑定上下文.
这里要注意method和function的区别:method是对象的属性,function是first class的data type
9.react在onCheck事件中给this.checkedIds赋值报错: Can't add property name, object is not extensible
原来我没有在constructor中bind(this); 没有bind的话,onCheck方法中的this是React.createElement产生的对象, bind后是自己写的class
8. 网页上需要加时间插件,点击打开,移动到外部关闭
react的input捕获不到onfocus事件,可以用ref获取dom对象以此得到callback
在关闭插件时遇到问题:onMouseOut触发条件不对,触发的地方太多了。因为浏览器存在两种事件流:事件冒泡,事件捕获。
事件冒泡的定义:事件按照从最特定的事件目标逐级向上传播到最不特定的事件目标(document对象)的顺序。
子标签的onmouseover事件和onmouseout事件无论有没有都会触发,如果没有会传递到父元素。
所以需要阻止子元素响应父元素的onmouseout事件
这里换了一个方案,点击外部关闭插件。onBlur也存在时间捕获的问题,但h5之后可以通过tabindex来避免这个问题
<div tabindex="-1" style="100px; height:100px; position:relative;"
onfocus = "document.getElementById('test').style.display='block'"
onblur = "document.getElementById('test').style.display='none'">
<div>Test</div>
</div>
<div style="position: absolute; top:20px; display:none;" id="test">
TestTestTestTest
</div>
7. react中checkbox类型的input, 获取事件值时不是event.target.value, 而是event.target.checked。
另外, input的checked属性无法区分string 类型的"true","false"
6.
modifyOrDelete(event) {
let item = {
ContractId: event.currentTarget.childNodes[0].innerHTML //在setState的异步方法里不能调用,react有优化
}
this.setState(function (prevState) {
if(!prevState.doModifyAndDeleteItem) {
return {doModifyAndDeleteItem: true, modifiedOrDeletedItem: item}
}
});
5. react的css样式问题, 因为react追求的是UI组件化,css定义用不了class选择器,这点不太方便, 一个style只能用一个变量赋值
通过拼装style变量完成css样式的复用
4. 增加react层级来优化重新render的范围
我现在的做法是在render方法的return 之前发起http请求,将查到的数据通过修改state来展示.
有的交互不需要发起http请求,在中间加一个state层级,通过避免重新渲染这个顶级Component来减少不必要的调用
3. setState(function(prevState){})
本来以为只要不return state就不会更新,结果是只要调用setState方法就会重新render,与state是否有变化无关
2. onClick怎么传值
<tr key={country.Id}>
<td id={country.Id} onClick={this.updateOrModify}>{country.FullName}</td>
<td id={country.Id} onClick={this.updateOrModify}>{country.Comment}</td>
</tr>
目前的笨办法是把每个子标签都写上onClick方法,通过event.target.id传值,或者写在<tr>上,把<tr>的z-index调高(不推荐)
update:
放在tr里,通过event.currentTarget获取
1.react中关于state的管理,如果涉及到Lifting state up的问题,怎么将sub component的值往上传:
官方文档有,通过传递function的方式,上级传递下来的function的闭包范围可以操作两者的变量