那些React-Native踩過的的坑


    這幾天開始邊學邊做新模式,也踩了不少坑,所以會記錄下來--俗話說好記心不如爛筆頭,何況還沒有一顆好記心(-_-)。

   從學React-Native開發功能模塊大概5天,有些體會:1如果說按產品原型去做一樣東西,那是容易的,但是這會造成很多問題,第一個是機器人一樣寫代碼,你不會從項目整體思考,代碼的質量也比較差而且不容易維護),所以決定每天寫個博客,看1個小時React-native基礎點。

   0x01 關於Reac-Native調試命令react-native start的坑

   windows環境下, 開啟react項目(暫且將命令服務稱之為后台)后台再經過一些操作后,馬上會出現下圖狀態operation not permitted,lstat '..\.git\inde.lock'..錯誤

   

   一開始根據翻譯的話說是對這個文件的操作不被允許:

   第一點:很容易想到是文件權限的問題,可以打開這個路徑下的文件屬性(.git文件夾是項目倉庫,默認是隱藏的,文件管理設置顯示隱藏的項目)發現讀寫屬性沒問題

   第二點:cmd命令沒有以管理員方式運行,實測其實沒效果

   第三點:查看了github的Reac-Native issues 然后發現找到兩個已經關閉的issues

   

   下面列了下方法:

      1其實是node_modules/react-native/local-cli/server/server.js 文件中找到process.on('uncaughtException'行的然后注釋process.exit(0)退出進程的代碼,親測可用比較方便。

      2未安裝watchman引起的,這種方法沒有實測

   

    參考http://stackoverflow.com/questions/38701115/windows-android-react-native-server-crashes-very-often/38831876#38831876

    0x02 布局頁面中的某個部分頻繁刷新

   我這邊做一個ListView中的一些item的需要倒計時顯示,一開始我把他放在整個item的render布局中然后發現加載5個定時器的時候切換頁面的時候特別卡,后面嘗試把頁面切換的時候把定時器移除(一開始認為切換后再回來頁面會重新創建),但是發現其實不會。后面聽了技術老大的說封裝這個定時器組件,這里涉及到react-native底層原理,因為放在整個item的布局中的話,每次更新時間其實是用diff算法計算這次的virtual dom與上次的virtual dom不同之處,如果不一樣更新不同的地方,而如果item中的布局比較復雜的話,計算會比較耗時,但是如果封裝到組件中如果更新時間只需要計算<View><Text></Text></View>很簡單的virtual dom,效率上會提升很多,實測效率提升很多。

         封裝再單獨組件中檢測執行 兩個定時器消耗697ms與816ms 內存開銷還沒測

  

  關於這個點后續會實測具體時間來作說明。

  0x03 關於state的實用用法

  在react-native中state代表動態改變值的狀態,但如何應用到開發中是一個關鍵點?

  應用方向:如果頁面中觸發一個事件會引起多個控件改變,那么我們只要設置設定一個state的屬性,不同地方判斷其值,如果改變的話對應所有帶有屬性的布局都會更新,相當於簡單代碼實現多控件刷新。

  具體例子:

   0x01網絡請求的不同狀態:請求成功-無內容 請求成功-有數據 解析失敗 接口錯誤 

   0x02播放器的詳情頁中點擊播放按鈕 進度條開始往前走 可以設置一個播放狀態

          然后若點擊播放

          1按鈕改變按鈕圖標

          2播放進度條開始往前走

  0x03 關於react-native中ListView加載數據細節

    頁面中經常會有上拉加載數據的情況,若使用

    

    那時候弄的頁面比直接使用快2.5秒左右,尤其是頁面item布局復雜的話效果更明顯。

  0x04 Undefined is not a function(React.findNodehandle)

import {
  ...
  findNodeHandle,
  ...
} from 'react-native';
不使用類名調用方法:
 findNodeHandle(ref)

0x05 redux-form問題

 

問題:代碼如下

_onPress(index,value) {
this.setState({currentIndex: index});
}

render() {
        const {title, menuData}=this.props;
        return (<div className="sub-sideBar">
            <div className="title">{title}</div>
            {menuData.map((value, index) => {
                if(!value)
                    return;
                return <a key={index} onClick={this._onPress(index,value)}
                          className={this.getItemCssClasses(index)}>
                    <span>{value.title}</span>
                </a>;
            })}
        </div>);
    }

 

warning.js:36Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

分析:

  1.   你會發現onClick={this._onPress(index,value)}
    雖然我們沒有點擊下面的超鏈接,但是這里會無限打印log,所以說react會自動執行下面的onClick表達式,從而得到真正的onclick函數句柄,進而導致無限修改state與reRender,直到內存溢出。

 

解決方法:

  1. 因此可以是onClick={this._onPress.bind(2)}或者onClick={()=>{this._onPress(2)}},  
  2.  后者當react執行onClick表達式的時候得到的是一個函數  

參考:https://github.com/facebook/react/issues/7177

     http://blog.csdn.net/liangklfang/article/details/53694994

持續更新中。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM