在 React 項目中全量使用 Hooks

此文章只是整理了在 React 項目開發中經常使用的一些 Hooks,具體每一個的坑,以及詳細解刨後續繼續更新,並會加上連接。javascript

React Hooks

Hooks 只能用於函數組件當中。html

useState

import React, { useState } from 'react';

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

此方法會返回兩個值:當期狀態和更新狀態的函數。效果同 this.statethis.setState,區別是 useState 傳入的值並不必定要對象,而且在更新的時候不會吧當前的 state 與舊的 state 合併。java

useEffect

import React, { useState, useEffect } from 'react';

let timer = null;

const Component = () => {
  const [count, setCount] = useState(0);
  
  // 相似於 class 組件的 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    document.title = `You clicked ${count} times`;
    
    timer = setInterval(() => {
      // events ...
    }, 1000)
    
    return () => {
      // 相似 componentWillUnmount
      // unmount events ...
      clearInterval(timer); // 組件卸載 移除計時器
    };
  }, [count]);
  
  // ...
}
複製代碼

若是 useEffect 第二個參數數組內的值發生了變化,那麼 useEffect 第一個參數的回調將會被再執行一遍。react

useCallback

import React, { useCallback } from 'react';

const Component = () => {
  const setUserInfo = payload => {}; // request api

  const updateUserInfo = useCallback(payload => {
    setUserInfo(Object.assign({}, userInfo, payload));
  }, [userInfo]);
  
  return (
    <UserCard updateUserInfo={updateUserInfo}/> ) } 複製代碼

useCallback 會在二個參數的依賴項發生改變後才從新更新,若是將此函數傳遞到子組件時,每次父組件渲染此函數更新,就會致使子組件也從新渲染,能夠經過傳遞第二個參數以免一些非必要性的渲染。web

在一些特殊狀況下傳遞此參數還能夠解決一些由靜態做用域致使的問題。redux

useMemo

import React, { useMemo } from 'react';

const Component = () => {
  const [count, setCount] = useState(0);
 
  const sum = useMemo(() => {
    // 求和邏輯
    return sum;
  }, [count]);
  
  return <div>{sum}</div>
}
複製代碼

useMemo 的用法跟 useCallback 同樣,區別就是一個返回的是緩存的方法,一個返回的是緩存的值。上述若是依賴值 count 不發生變化,計算 sum 的邏輯也就只會執行一次,從而性能。api

這是以後更新的:useCallback 與 useMemo 詳解 歡迎閱讀。數組

Redux Hooks

useSelector

import { shallowEqual, useSelector } from 'react-redux';

const Component = () => {
  const userInfo = useSelector(state => state.userInfo, shallowEqual);
  
  // ...
}
複製代碼

useSelector 的第二個參數是一個比較函數,useSelector 中默認使用的是 === 來判斷兩次計算的結果是否相同,若是咱們返回的是一個對象,那麼在 useSelector 中每次調用都會返回一個新對象,因此因此爲了減小一些不必的 re-render,咱們可使用一些比較函數,如 react-redux 自帶的 shallowEqual,或者是 Lodash 的 _.isEqual()、Immutable 的比較功能。緩存

useDispatch

import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';

const Compnent = () => {
  const dispatch = useDispatch();
  const clearUserInfo = useCallback(
    () => dispatch({ type: 'clearUserInfo' }),
    [dispatch]
  );
  
  return (
    <button onClick={clearUserInfo}>click</buttn>
  )
}
複製代碼

使用 dispatch 來調度操做,加上 useCallback 來減小沒必要要的渲染。react-router

React Router Hooks

useHistory

import { useHistory } from 'react-router';

const Compnent = () => {
  const history = useHistory();
  
  return (
    <button onClick={() => history.push('/home')}>go home</buttn>
  )
}
複製代碼

useHistory

import React, { useEffect } from 'react';
import { useLocation } from 'react-router';

const Compnent = () => {
  const location = useLocation();
  
  useEffect(() => {
    // ...
  }, [location])
  
  return (
    <button onClick={() => history.push('/home')}>go home</buttn>
  )
}
複製代碼

URL一發生變化,他將返回新的 location

useParams

import { useParams, useEffect } from 'react-router';

const Component = () => {
  const params = useParams();
  
  const getUserInfo = () => {}; // request api
  
  useEffect(() => {
    // parms 的 uid 發生變化就會從新請求用戶信息
    getUserInfo(params.uid);
  }, [params.uid]);
  
  // ...
}
複製代碼

useParams 返回 react-router 的參數鍵值對

useRouteMatch

import { useRouteMatch } from 'react-router';

const Component = () => {
  const match = useRouteMatch('/login');
  
  // ...
}
複製代碼

useRouteMatch 傳入一個參數 path,用來判斷當前路由是否能匹配上傳遞的 path,適用於判斷一些全局性組件在不一樣路由下差別化的展現。

結語

使用 Hooks 能爲開發提高很多效率,但並不表明就要拋棄 Class Component,依舊還有不少場景咱們還得用到它,好比須要封裝一個公共的可繼承的組件...

參考

相關文章
相關標籤/搜索