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="width: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的閉包范圍可以操作兩者的變量
文章列表