React Hooks最佳技術實踐(一)

原文地址:博客html

前言

React 16.8版本發佈於2019年2月6號,它帶來了Hooks特性,可以讓咱們不編寫class的狀況下也能使用state以及其餘的React特性。一個新技術的誕生必然會影響原來的思惟模式,在最初的應用中也會遇見不少意想不到的場景和陷阱,這就須要咱們在使用他們前清楚的知道哪裏可能會有潛在的問題,有哪些更加完善的寫法,這也是寫本文章的初衷。咱們團隊在7月份開始在新項目中全面使用Hooks技術,期間也遇到和解決了不少的麻煩和問題,同時讓咱們對於函數式組件有了更深的理解。react

在本文開始前,須要你掌握React官方中關於React Hooks的基礎知識。不少坑在官方的FAQ已經說明了,常常閱讀官方文檔也是個良好的習慣。後端

本文介紹的是我在使用Hooks的過程當中碰見的問題和技巧,可能還有其餘我沒發現的或者沒有寫出來的,歡迎和我交流,但願經過閱讀本文可以讓你快速的掌握Hooks的陷阱和技巧,開發出高質量的函數式組件。那咱們就先從useState開始。數組

useState

在Class Component中,使用state來存儲組件的狀態,用setState來更新,在Hooks中提供了useStateAPI來建立一個state。閉包

state結構

useState接收一個initialState,同時返回一個state以及更新state的函數。initialState可使用基礎數據類型,也可使用數組、對象等引用數據類型。這裏建議根據state的關聯度和做用來決定是否使用多個useState來定義state。函數

在下面的例子中,咱們根據後端接口返回的數據{data: [Tom, Jerry], total: 2, result: true}來設置state數據。第一種寫法直接將全部的請求參數和返回數據所有存儲到一個userState中,咱們來分析下爲什麼不推薦這麼作。oop

首先,返回的數據中存在不須要存儲在state中的數據字段result。其次,將data與requestParams放在一個state中看似簡單,只須要維護一個userState,可是若是須要在useEffect中依賴data或者requestParams將會很是的麻煩,並且每次獲取後端返回的數據都將須要一同更新requestParams優化

不建議的寫法ui

const [userState, setUserState] = useState({
    data: [],
    total: 0,
    requestParams: { id: 1 },
    result: true
})
複製代碼

推薦的寫法spa

const [userData, setUserData] = useState({ data: [], total: 0 })
const [userParams, setUserParams] = useState({ id: 1 })
複製代碼

避免重複計算

若是initialState爲函數,則useState在初始化時會馬上執行該函數和獲取函數的返回值,在沒有任何返回值得狀況下爲undefined。這裏須要注意的是每次組件re-render都會致使useState中的函數從新計算,這裏可使用閉包函數來解決問題。在優化後只有組件初始化時纔會執行一遍loop函數。

本例子能夠在CodeSandbox中查看

優化前

const loop = () => {
  console.log("calc!");
  let res = 0;
  for (let i = 0, len = 1000; i < len; i++) {
    res += i;
  }
  return res;
};

const [value, setValue] = useState(loop());
複製代碼

優化後

const App = () => {
  const [value, setValue] = useState(() => {
    return loop();
  });
}
複製代碼

更新state

在某些狀況下若是須要從上一個state來計算當前的state,可能會想到使用下面優化前的方法。可是,須要注意的一點是在某些閉包的場景下面count可能不是最新的,這樣會致使計算錯誤。這裏推薦使用官方給出的方法。

優化前

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>+</button>
}
複製代碼

優化後

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
}
複製代碼

下一篇文章介紹useEffectuseLayoutEffect的使用技巧。

相關文章
相關標籤/搜索