1. 程式人生 > 其它 >react-hook學習

react-hook學習

hooks技術不是一門新的技術,而是一種設計思想。

自定義hooks更像是一種約定,而不是一種功能,一般以use開頭的,並呼叫其他hook,就可以稱為自定義Hooks(自定義的Hook中,最裡面一定是使用了useEffect函式)。

注意:

每次呼叫 setSate的類似函式(例如:setCount),都會從新執行整個函式元件。

useState()

const [count, setCount] = useState(0);
/*
初始化一個狀態變數並帶有初始值(0)
	count:初始化的狀態變數
	setCount:改變這個狀態的函式(類似與setState())
*/

useContext()

在類元件中有constructor函式,可以用來接收pops屬性的值。

但是函式式元件中沒有constructor函式,也就沒有了接受props屬性的地方,那麼在這種情況下父元件想向子元件傳值就有問題了,為了解決這個問題,引入了useContext()函式。

作用:

  • 實現跨越元件層級傳遞變數,提供全域性共享。

    useContext()解決元件之間傳遞的問題。與useReducer()配合使用,可以實現類似於redux的功能。

    redux整個應用中統一狀態管理。

  • context是對它所包含的元件樹提供全域性共享資料的一種技術。

cont [state, dispatch] = useContext(context)
/*
useContext(context)
接收一個context引數,這個context是由React.createContext(defaultValue)所建立的
*/

const {Provider, Consumer} = context = React.createContext(defaultValue);
function Parent(){
    const [count, setCount] = useState(0);
    return(
    	<>
        	<div>{count}</div>
        	<button onClick={()=>{setCount(count+1)}}>Click Me</button>
        	<Provider value={count}>
        		<Child />
        	</Provider>
        </>
    )
}

function Child(){
    const count = useContext(context);
    return (<h2>{count}</h2>)
}
/*
既然是解決父元件想子元件傳值的問題的,那麼父元件是如何向子組傳遞值的呢?
1. 父元件需要把將要傳遞的值放到context中
2. 子元件使用useContext()獲取父元件傳遞的值

//定義一個父元件最外層的context變數(可以單獨成檔案,然後再父元件和子元件中分別引入使用)
const {Provider, Consumer} = context = React.createContext(defaultValue);
	Provider是傳值方(context.Providert)
	Consumer是接收方(context.Consumer)

function Parent(){
    const [count, setCount] = useState(0);
    return(
    	<>
        	<div>{count}</div>
        	<button onClick={()=>{setCount(count+1)}}>Click Me</button>
        	
        	//將父元件要傳遞的值放入到context中
        	<Provider value={count}>
        		//這樣父元件中的count發生變化後,子元件的值就會發生改變
        		<Child />
        	</Provider>
        </>
    )
}

//重點 重點  重點
function Child(){
	//使用useContext()接收父元件傳遞過來的屬性值,這裡useContext會獲取到離子元件最近的父元件傳遞過來的值
	//同時需要注意的是,這裡的context必須要與父元件是相同的context,才可以實現資料的共享。
    const count = useContext(context);
    return (<h2>{count}</h2>)
}
*/

useEffect(func,[deps])

相當於類元件中的componentDidMount()componentDidUpdate()以及componentWillUnmount()的合併,即完成DOM修改後的呼叫函式

func:表示DOM渲染後需要執行的函式體。

deps:表示這個useEffect()的依賴項,依賴項發生改變,就會再次執行func函式體。

useEffect()如果函式中由需要清除的副作用,就需要在useEffect()函式體內返回一個函式

useEffect(()=>{
    //....
    return ()=>{
        //需要清除的副作用
    }
},[])

useReducer(reducer,initState)

useReducer(reducer,initState)用來管理state狀態(多個狀態需要同時修改時,建議使用:例如:登入驗證)

import React,{useReducer} from 'react'

export default function ReducerDemo() {
    const [count, dispath] = useReducer((state,action)=> {
       switch(action){
           case 'add':
                return state + 1;
            case 'sub':
                return state - 1;
            default:
                return state;
       }
    }, 0);
    return (
        <div>
            <h1 className="title">{count}</h1>
            <button className="btn is-primary"
                onClick={()=> dispath('add')}
                >Increment</button>
            <button className="btn is-warnning"
                onClick={()=> dispath('sub')}
                >Decrement</button>
        </div>
    )
}

/*
const [count, dispatch] = useReducer(reducer,initState)
	reducer: 一個負責改變state的值的函式,
		這個函式由兩個引數:reducer(state,action)
			state:初始狀態
			action:reducer函式會根據action的型別來判斷將怎麼改變這個state
	count:狀態改變後的值
	dispatch:一個觸發reducer的機制,在元件中呼叫。(重要)
	
	
	return [
		...state,
		{
			id:10,
			name:"haha"
		}
	]
	這句話的意思是,先copy一個state,然後修改這個state
*/

useRef(initValue)

const like = useRef(0);
//貫穿元件的整個生命週期,元件重新渲染後like的值不會改變,保持原值。

useLayoutEffect(func,[deps])

佈局副作用:

​ useEffect在瀏覽器渲染完成後執行

​ useLayoutEffect在瀏覽器渲染完成前執行

特點:

​ useLayoutEffect總是比useEffect先執行

​ useLayoutEffect裡面的任務最好影響layout(佈局)

注意:

​ 最好是使用useEffect(為了使用者體驗最好)

useCallback(func,[deps])

解決:函式元件的每一次呼叫都會執行其內部的所有邏輯,那麼會帶來較大的效能損耗。

useMemo()useCallback()就是解決這些問題的殺手鐗。

  • useMemo() 返回快取的變數
  • useCallback() 返回快取的函式
const funA = useCallback(funcB, [deps]);
//將傳遞進來的funcB返回給funcA,並且將這個結果進行快取,如果依賴改變了,就會返回新的函式。

注意:

useMemo(),useCallback(),useEffect()都是自帶閉包的,即元件每次重新渲染,其都會捕獲當前元件函式上下文中的狀態(stat,props),所以它反映的也都是元件當前的狀態。

useMemo(initValue)

類似與useCallback,只是useMemo返回的是快取的變數。

const valueA = useMemo(2);
//valueA變數會一直保留,重新渲染元件時不會重新定義這個變數。