欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React Hook用法示例詳解(6個(gè)常見(jiàn)hook)

 更新時(shí)間:2021年04月28日 16:45:41   作者:是明啊  
這篇文章主要介紹了React Hook用法詳解(6個(gè)常見(jiàn)hook),本文通過(guò)實(shí)例代碼給大家介紹了6個(gè)常見(jiàn)hook,需要的朋友可以參考下

1、useState:讓函數(shù)式組件擁有狀態(tài)

用法示例:

// 計(jì)數(shù)器
import { useState } from 'react'
const Test = () => {
    const [count, setCount] = useState(0);
    return (
        <>
            <h1>點(diǎn)擊了{(lán)count}次</h1>
            <button onClick={() => setCount(count + 1)}>+1</button>
        </>
    );
}
export default Test

PS:class組件中this.setState更新是state是合并, useState中setState是替換。例如:

// 錯(cuò)誤示例
import { useState } from 'react'
const Test = () => {
    const [counts, setCounts] = useState({
        num1: 0,
        num2: 0
    });
    return (
        <>
            <h1>num1:{counts.num1}</h1>
            <h1>num2:{counts.num2}</h1>
            <button onClick={() => setCounts({ num1: counts.num1 + 1})}>num1+1</button>
            <button onClick={() => setCounts({ num2: counts.num2 + 1})}>num2+1</button>
        </>
    );
}
export default Test

可以看到useState中setState是替換,不會(huì)合并,正確更新:

import { useState } from 'react'
const Test = () => {
    const [counts, setCounts] = useState({
        num1: 0,
        num2: 0
    });
    return (
        <>
            <h1>num1:{counts.num1}</h1>
            <h1>num2:{counts.num2}</h1>
            <button onClick={() => setCounts({ ...counts, num1: counts.num1 + 1})}>num1+1</button>
            <button onClick={() => setCounts({ ...counts, num2: counts.num2 + 1})}>num2+1</button>
        </>
    );
}
export default Test

2、useEffect:副作用,取代生命周期

用法示例,在class組件中如果需要在組件掛載后和數(shù)據(jù)更新后做同一件事,我們會(huì)這樣做:

componentDidMount() {
    // 做一些事
}
componentDidUpdate() {
    // 做一些事
}

可以看出來(lái),如果邏輯復(fù)雜后,代碼看起來(lái)不優(yōu)雅,且容易造成邏輯混亂,而使用useEffect:

useEffect(() => {
    // 做一些事
});

此刻已經(jīng)看到了useEffect的基本用法,除此之外,他還可以綁定觸發(fā)更新的依賴狀態(tài),默認(rèn)是狀態(tài)中任何數(shù)據(jù)發(fā)生變化副作用都會(huì)執(zhí)行,如:

import { useState, useEffect } from 'react'
const Test = () => {
    const [count1, setCount1] = useState(0);
    const [count2, setCount2] = useState(0);
    useEffect(() => {
        console.log('useEffect觸發(fā)了')
    });
    return (
        <>
            <h1>count1:{count1}</h1>
            <h1>count2:{count2}</h1>
            <button onClick={() => setCount1(count1 + 1)}>count1+1</button>
            <button onClick={() => setCount2(count2 + 1)}>count2+1</button>
        </>
    );
}
export default Test

將上述代碼useEffect第二個(gè)參數(shù)傳入需要綁定的狀態(tài),可綁定多個(gè):

// 語(yǔ)法:useEffect(回調(diào)函數(shù),[依賴值])
useEffect(() => {
    console.log('useEffect觸發(fā)了')
}, [count1]);

可以看到,只有綁定的count1發(fā)生變化才會(huì)觸發(fā),如果傳空數(shù)組則任何狀態(tài)發(fā)生變化都不會(huì)觸發(fā),此時(shí)useEffect的作用就類似class組件中的componentDidMount,所以發(fā)送請(qǐng)求通常也會(huì)在此執(zhí)行。

清理副作用

在上面的操作中都不用清理的副作用,然而,有些副作用是需要去清理的,不清理會(huì)造成異常甚至內(nèi)存泄漏,比如開(kāi)啟定時(shí)器,如果不清理,則會(huì)多次開(kāi)啟,從上面可以看到useEffect的第一個(gè)參數(shù)是一個(gè)回調(diào)函數(shù),可以在回調(diào)函數(shù)中再返回一個(gè)函數(shù),該函數(shù)可以在狀態(tài)更新后第一個(gè)回調(diào)函數(shù)執(zhí)行之前調(diào)用,具體實(shí)現(xiàn):

useEffect(() => {
    // 設(shè)置副作用
    return () => {
        // 清理副作用
    }
});

3、useContext:跨組件共享數(shù)據(jù)

React.createContext();創(chuàng)建一個(gè)TestContext對(duì)象
TestContext.Provider包裹子組件
數(shù)據(jù)放在<TestContext.Provider value={value}>的value中
子組件中通過(guò)useContext(TestContext)獲取值

import React, { useContext, useState } from 'react';
const TestContext = React.createContext();
const Parent = () => {
    const [value, setValue] = useState(0);
    return (
        <div>
            {(() => console.log("Parent-render"))()}
            <button onClick={() => setValue(value + 1)}>value + 1</button>
            <TestContext.Provider value={value}>
                <Child1 />
                <Child2 />
            </TestContext.Provider>
        </div>
    );
}
const Child1 = () => {
    const value = useContext(TestContext);
    return (
        <div>
            {(() => console.log('Child1-render'))()}
            <h3>Child1-value: {value}</h3>
        </div>
    );
}
const Child2 = () => {
    return (
        <div>
            {(() => console.log('Child2-render'))()}
            <h3>Child2</h3>
        </div>
    );
}
export default Parent

至此數(shù)據(jù)實(shí)現(xiàn)共享了,但是可以看到在TestContext中的共享數(shù)據(jù)只要發(fā)生變化,子組件都會(huì)重新渲染,Child2并沒(méi)有綁定數(shù)據(jù),不希望他做無(wú)意義的渲染,可以使用React.memo解決,實(shí)現(xiàn):

const Child2 = React.memo(() => {
    return (
        <div>
            {(() => console.log('Child2-render'))()}
            <h3>Child2</h3>
        </div>
    );
});

4、useCallback:性能優(yōu)化

語(yǔ)法:

// useCallback(回調(diào)函數(shù),[依賴值])
const handleClick = useCallback(()=> {
    // 做一些事
}, [value]);

useCallback返回的是一個(gè) memoized(緩存)函數(shù),在依賴不變的情況下,多次定義的時(shí)候,返回的值是相同的,他的實(shí)現(xiàn)原理是當(dāng)使用一組參數(shù)初次調(diào)用函數(shù)時(shí),會(huì)緩存參數(shù)和計(jì)算結(jié)果,當(dāng)再次使用相同的參數(shù)調(diào)用該函數(shù)時(shí),會(huì)直接返回相應(yīng)的緩存結(jié)果。

優(yōu)化性能例子:

import React, { useState, useCallback, memo } from 'react';
const Parent = () => {
    const [value1, setValue1] = useState(0);
    const [value2, setValue2] = useState(0);
    const handleClick1 = useCallback(()=> {
        setValue1(value1 + 1);
    }, [value1]);
    const handleClick2 = useCallback(()=> {
        setValue2(value2 + 1);
    }, [value2]);
    return (
        <>
            {(() => console.log("Parent-render"))()}
            <h3>{value1}</h3>
            <h3>{value2}</h3>
            <Child1 handleClick1={handleClick1} />
            <Child2 handleClick2={handleClick2} />
        </>
    );
}
const Child1 = memo(props => {
    return (
        <div>
            {(() => console.log("Child1-render"))()}
            <button onClick={() => props.handleClick1()}>value1 + 1</button>
        </div>
    );
});
const Child2 = memo(props => {
    return (
        <div>
            {(() => console.log("Child2-render"))()}
            <button onClick={() => props.handleClick2()}>value2 + 1</button>
        </div>
    );
});
export default Parent

useCallback返回的是一個(gè)memoized回調(diào)函數(shù),僅在其中綁定的一個(gè)依賴項(xiàng)變化后才更改可防止不必要的渲染,在跨組件共享數(shù)據(jù)中舉例的事件是在父組件中點(diǎn)擊觸發(fā),而現(xiàn)在是使用狀態(tài)提升,在父組件中傳遞方法供子組件調(diào)用,每次render時(shí)函數(shù)也會(huì)變化,導(dǎo)致子組件重新渲染,上面例子useCallback將函數(shù)進(jìn)行包裹,依賴值未發(fā)生變化時(shí)會(huì)返回緩存的函數(shù),配合React.memo即可優(yōu)化無(wú)意義的渲染。

5、useMemo:性能優(yōu)化

語(yǔ)法:

// useMemo(回調(diào)函數(shù),[依賴值])
useMemo(() => {
    // 做一些事情
},[value]);

先看一個(gè)例子:

import React, { useState } from 'react'
const Test = ()=> {
    const [value, setValue] = useState(0);
    const [count, setCount] = useState(1);
    const getDoubleCount = () => {
        console.log('getDoubleCount進(jìn)行計(jì)算了');
        return count * 2;
    };
    return (
        <div>
            <h2>value: {value}</h2>
            <h2>doubleCount: {getDoubleCount()}</h2>
            <button onClick={() => setValue(value + 1)}>value+1</button>
        </div>
    )
}
export default Test

可以看到getDoubleCount依賴的是count,但value發(fā)生變化它也重新進(jìn)行了計(jì)算渲染,現(xiàn)在只需要將getDoubleCount使用useMemo進(jìn)行包裹,如下:

import React, { useState, useMemo } from 'react'
const Test = ()=> {
    const [value, setValue] = useState(0);
    const [count, setCount] = useState(1);
    const getDoubleCount = useMemo(() => {
        console.log('getDoubleCount進(jìn)行計(jì)算了');
        return count * 2;
    },[count]);
    return (
        <div>
            <h2>value: {value}</h2>
            <h2>doubleCount: {getDoubleCount}</h2>
            <button onClick={() => setValue(value + 1)}>value+1</button>
        </div>
    )
}
export default Test

現(xiàn)在getDoubleCount只有依賴的count發(fā)生變化時(shí)才會(huì)重新計(jì)算渲染。

useMemo和useCallback的共同點(diǎn):

  • 接收的參數(shù)都是一樣的,第一個(gè)是回調(diào)函數(shù),第二個(gè)是依賴的數(shù)據(jù)
  • 它們都是當(dāng)依賴的數(shù)據(jù)發(fā)生變化時(shí)才會(huì)重新計(jì)算結(jié)果,起到了緩存作用

useMemo和useCallback的區(qū)別:

  • useMemo計(jì)算結(jié)果是return回來(lái)的值,通常用于緩存計(jì)算結(jié)果的值
  • useCallback計(jì)算結(jié)果是一個(gè)函數(shù),通常用于緩存函數(shù)

6、useRef用法:例如要實(shí)現(xiàn)點(diǎn)擊button按鈕使input輸入框獲得焦點(diǎn):

import React, { useState, useMemo } from 'react'
const Test = ()=> {
    const [value, setValue] = useState(0);
    const [count, setCount] = useState(1);
    const getDoubleCount = useMemo(() => {
        console.log('getDoubleCount進(jìn)行計(jì)算了');
        return count * 2;
    },[count]);
    return (
        <div>
            <h2>value: {value}</h2>
            <h2>doubleCount: {getDoubleCount}</h2>
            <button onClick={() => setValue(value + 1)}>value+1</button>
        </div>
    )
}
export default Test

這樣看起來(lái)非常像React.createRef(),將上面代碼中的useRef()改成React.createRef()也能實(shí)現(xiàn)同樣的效果,那為什么要設(shè)計(jì)一個(gè)新的hook?難道只是會(huì)了加上use,統(tǒng)一hook規(guī)范?
事實(shí)上,它們確實(shí)不一樣。

官網(wǎng)的說(shuō)明如下:

useRef returns a mutable ref object whose .current property is initialized to the passed
argument (initialValue). The returned object will persist for the full lifetime of the component.

翻譯:

簡(jiǎn)單來(lái)說(shuō),useRef就像一個(gè)儲(chǔ)物箱,你可以隨意存放任何東西,再次渲染時(shí)它會(huì)去儲(chǔ)物箱找,createRef每次渲染都會(huì)返回一個(gè)新的引用,而useRef每次都會(huì)返回相同的引用。

到此這篇關(guān)于React Hook用法詳解(6個(gè)常見(jiàn)hook)的文章就介紹到這了,更多相關(guān)React Hook用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React中react-redux和路由詳解

    React中react-redux和路由詳解

    這篇文章主要介紹了React中react-redux和路由詳解,redux早期被設(shè)計(jì)成可以在各個(gè)框架中使用,因此在不同的框架中使用的時(shí)候,要引入相應(yīng)的插件,感興趣的朋友可以繼續(xù)學(xué)習(xí)下面文章
    2022-08-08
  • react-native聊天室|RN版聊天App仿微信實(shí)例|RN仿微信界面

    react-native聊天室|RN版聊天App仿微信實(shí)例|RN仿微信界面

    這篇文章主要介紹了react-native聊天室|RN版聊天App仿微信實(shí)例|RN仿微信界面,需要的朋友可以參考下
    2019-11-11
  • React和Vue中實(shí)現(xiàn)錨點(diǎn)定位功能

    React和Vue中實(shí)現(xiàn)錨點(diǎn)定位功能

    在React中,可以使用useState和useEffect鉤子來(lái)實(shí)現(xiàn)錨點(diǎn)定位功能,在Vue中,可以使用指令來(lái)實(shí)現(xiàn)錨點(diǎn)定位功能,在React和Vue中實(shí)現(xiàn)錨點(diǎn)定位功能的方法略有不同,下面我將分別介紹,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • concent漸進(jìn)式重構(gòu)react應(yīng)用使用詳解

    concent漸進(jìn)式重構(gòu)react應(yīng)用使用詳解

    這篇文章主要為大家介紹了concent漸進(jìn)式重構(gòu)react應(yīng)用的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 利用React高階組件實(shí)現(xiàn)一個(gè)面包屑導(dǎo)航的示例

    利用React高階組件實(shí)現(xiàn)一個(gè)面包屑導(dǎo)航的示例

    這篇文章主要介紹了利用React高階組件實(shí)現(xiàn)一個(gè)面包屑導(dǎo)航的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 詳解React項(xiàng)目中碰到的IE問(wèn)題

    詳解React項(xiàng)目中碰到的IE問(wèn)題

    這篇文章主要介紹了React項(xiàng)目中碰到的IE問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • react Input組件Compositionstart和Compositionend事件

    react Input組件Compositionstart和Compositionend事件

    這篇文章主要為大家介紹了Compositionstart和Compositionend事件之于react組件庫(kù)Input組件的坑解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法

    React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法

    今天講一下如何實(shí)現(xiàn)自定義標(biāo)題欄組件,我們都知道RN有一個(gè)優(yōu)點(diǎn)就是可以組件化,在需要使用該組件的地方直接引用并傳遞一些參數(shù)就可以了,這種方式確實(shí)提高了開(kāi)發(fā)效率。對(duì)React Native自定義標(biāo)題欄組件的實(shí)現(xiàn)方法感興趣的朋友參考下
    2017-01-01
  • react-router實(shí)現(xiàn)跳轉(zhuǎn)傳值的方法示例

    react-router實(shí)現(xiàn)跳轉(zhuǎn)傳值的方法示例

    這篇文章主要給大家介紹了關(guān)于react-router實(shí)現(xiàn)跳轉(zhuǎn)傳值的相關(guān)資料,文中給出了詳細(xì)的示例代碼,對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。
    2017-05-05
  • React?路由使用示例詳解

    React?路由使用示例詳解

    這篇文章主要介紹了React?路由使用,使用路由時(shí)需要為組件指定一個(gè)路由的path,最終會(huì)以path為基礎(chǔ),進(jìn)行頁(yè)面的跳轉(zhuǎn),具體使用先看個(gè)簡(jiǎn)單示例,該示例比較簡(jiǎn)單就是兩個(gè)Tab頁(yè)面的來(lái)回切換
    2022-05-05

最新評(píng)論