1. 程式人生 > 實用技巧 >react Hook

react Hook

概念:在不使用class元件的情況下,允許你使用state和react的其他特性

產生背景:在元件之間公用相同的邏輯往往很難,在以前的解決方案是:高階元件和render props 但是這類方案需要重新組織你的元件結構,這可能會很麻煩,使你的程式碼難以理解。

你可以使用 Hook 從元件中提取狀態邏輯,使得這些邏輯可以單獨測試並複用。Hook 使你在無需修改元件結構的情況下複用狀態邏輯。 這使得在元件間或社群內共享 Hook 變得更便捷。

Hooks不要在迴圈,條件或巢狀函式中以及class元件中呼叫 Hook,只在最頂層使用hook

不要在普通的函式中呼叫hook,只在react函式中呼叫hook

import React, { Component,useState } from 'react';
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types';

function Example(){
    // count變數的值是useState返回的第一個值  setCount是useState返回的第二個值
  //陣列解構 const [count,setCount] = useState(0) return ( <div> <p>you click {count} times</p> <button onClick={()=>setCount(count+1)}>點選我</button> </div> ) } ReactDOM.render(<Example />,document.getElementById('root'))

import React, { Component,useState,useEffect} from 'react';
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types';

function Example(){
    const [count,setCount] = useState(0)
    // 每次渲染完畢後都會執行useEffect
    //類似於class元件的  componentDidMount和componentDidUpdate
  //在執行當前 effect 之前對上一個 effect 進行清除
useEffect(()=>{ console.log(123) document.title = `You clicked ${count} times`
    //如果需要清除副作用 則需要返回一個函式來清除副作用,如果不需要清除副作用 則不需要返回一個函式 },[]) //如果第二個引數是一個空陣列 useEffect在掛載和解除安裝的時候只會執行一次
//React 會等待瀏覽器完成畫面渲染之後才會延遲呼叫 useEffect,因此會使得額外操作很方便。
return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count+1)}> Click me </button> </div> ) } ReactDOM.render(<Example />,document.getElementById('root'))//
import React, { Component,useState,useEffect} from 'react';
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types';

function Counter({initialCount}) {
    const [count, setCount] = useState(initialCount);
    return (
      <React.Fragment>
            Count: {count}
            <button onClick={() => setCount(initialCount)}>Reset</button>
            <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
            <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
            {/*  */}
        </React.Fragment>
    );
  }
  //上面更新狀態類似呼叫下面的 this.setState
  class App extends React.Component{
      constructor(props){
        this.setState((state)=>({

        }))
      }
  }

ReactDOM.render(<Counter initialCount={0} />,document.getElementById('root'))

如果你的更新函式返回值與當前 state 完全相同,則隨後的重渲染會被完全跳過。

useEffect的執行時機:等到瀏覽器完成佈局和繪製之後,傳給 useEffect 的函式會延遲呼叫

預設情況下,effect 會在每輪元件渲染完成後執行。這樣的話,一旦 effect 的依賴發生變化,它就會被重新建立。銷燬前一個effect 建立一個新的effect

然而,在某些場景下這麼做可能會矯枉過正。比如,在上一章節的訂閱示例中,我們不需要在每次元件更新時都建立新的訂閱,而是僅需要在 source prop 改變時重新建立。

要實現這一點,可以給 useEffect 傳遞第二個引數,它是 effect 所依賴的值陣列。

useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);