1. 程式人生 > >React踩坑筆記 —— React

React踩坑筆記 —— React

  • Webpack提供了自己的匯入方式require.include,但同時也支援commonjs規範或AMD規範的require語法,而Node.js使用的就是common.js,ES6的語法Import也會被Babel轉化成commonjs格式或者是AMD格式。
  • ES6、CommonJS的匯入是單例的;
  • 單頁應用預設直接加載出所有import的資源,所以:
    • JS中的全域性呼叫和表示式總會一開始就被執行,可以使用require()/import()語法實現動態載入、按需載入。可以配合Lazy(https://reactjs.org/docs/code-splitting.html#reactlazy)
      實現React元件懶載入 —— Lazy的原理即Promise+高階元件,在元件非同步載入完成後將解析值賦值給全域性物件。
    • CSS樣式可能會被覆蓋。
  • 一句話理解react:事件\樣式\選擇器,只屬於真實的DOM元素,Components最終被渲染成真實DOM。
  • 在重用社群自定義元件的時候,如果元件沒有給出樣式配置的鉤子(Hooks),那麼我們可以在瀏覽器除錯工具中,先找出指定元素的選擇器,然後去覆蓋先前樣式(Style)。
  • 在Props和State發生改變的時候,元件會發生更新,至於如何被更新,可以檢視“差分演算法”
  • 元件生命週期: 掛載、解除安裝發生在頁面載入和路由,更新發生在Props或State改變後;
  • 受控元件: 像表單元素這樣的,有狀態,並將狀態控制權交給React的元素稱為受控元件,受控元件必須滿足兩個條件:① 表單元素;② 狀態被React控制(顯式的value屬性)。所以如果你又想給出預設值又不想將表單元素變成受控元件,請使用defaultValue給出預設值;
  • 使用JSX語法的JS檔案必須匯入React ---- import React from 'react';
  • {}類似於eval()、模板引擎、JS``模板變數,先執行(執行模板中的表示式或呼叫)再渲染(將表示式執行的結果渲染出來),所以要特別注意{}中需要的是函式還是函式呼叫()
  • 使用Node.js(服務端)的包在瀏覽器編譯,會發生錯誤, 所以在npm install
    時要注意包的使用環境。
    Failed to compile
    Module not found: Can't resolve 'XXX' in 'xxx.lib' 在這裡插入圖片描述
  • Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
    函式作為React子函式無效。 如果從render props中返回{Component}而不是<Component />,則可能會發生這種情況。 或許你打算呼叫這個函式而不是返回它。
  • React.Children.only expected to receive a single React element child.,某個元件可以通過PropTypes作型別檢查,限制屬性型別
    MyComponent.propTypes = {
     children: PropTypes.element.isRequired
    };
    
  • redux中使用combineReducers時要注意其實現原理 —— 類似於如下程式碼:
    一般實現:
    const chatReducer = (state = defaultState, action = {}) => {
    return {
       chatLog: chatLog(state.chatLog, action),
       statusMessage: statusMessage(state.statusMessage, action),
       userName: userName(state.userName, action)
      }
    };
    
    combineReducers實現
    const combineReducers = reducers => {
    return (state = {}, action) => {
      return Object.keys(reducers).reduce(
        (nextState, key) => {
          nextState[key] = reducers[key](state[key], action);
          return nextState;
        },
        {} 
       );
     };
    };
    
    無論是針對哪個屬性拆分出來的子reducer,在任意dispatch發生時,都會被執行,所以定義subReducer時要注意在內部根據action.type來判斷執行路徑,如果這種typeaction不會影響subReducer對應的state.key,那麼一定要直接返回該state.key