react Hook
阿新 • • 發佈:2020-07-23
概念:在不使用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], );