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

React組件學(xué)習(xí)之Hooks使用

 更新時(shí)間:2022年08月31日 15:16:50   作者:小綿楊Yancy  
這篇文章主要介紹了React hooks組件通信,在開發(fā)中組件通信是React中的一個(gè)重要的知識(shí)點(diǎn),本文通過實(shí)例代碼給大家講解react hooks中常用的父子、跨組件通信的方法,需要的朋友可以參考下

一、前言

react組件分為類(class)組件和函數(shù)(function)組件。

class 組件是通過繼承模版類(Component、PureComponent)的方式開發(fā)新組件的,繼承是 class 本身的特性,它支持設(shè)置 state,會(huì)在 state 改變后重新渲染,可以重寫一些父類的方法,這些方法會(huì)在 React 組件渲染的不同階段調(diào)用,叫做生命周期函數(shù)。

function 組件不能做繼承,因?yàn)?function 本來就沒這個(gè)特性,并且函數(shù)式組件也沒有生命周期,所以react提供了一些 api 供函數(shù)來彌補(bǔ)函數(shù)組件的缺陷,這些 api 會(huì)在內(nèi)部的一個(gè)數(shù)據(jù)結(jié)構(gòu)上掛載一些函數(shù)和值,并執(zhí)行相應(yīng)的邏輯,通過這種方式實(shí)現(xiàn)了 state 和類似 class 組件的生命周期函數(shù)的功能,這種 api 就叫做 hooks。

二、React Hooks

其實(shí)我們已經(jīng)使用過一些hooks了,例如useState來實(shí)現(xiàn)響應(yīng)式的數(shù)據(jù)功能,使用useEffect實(shí)現(xiàn)類組件才擁有的組件生命周期,但是都沒有詳細(xì)地研究其參數(shù)和使用。

2.1 useState

state保存著當(dāng)前組件的狀態(tài),當(dāng)我們改變state,頁面ui就會(huì)自動(dòng)更新,及實(shí)現(xiàn)了響應(yīng)式。

類組件中使用state:

函數(shù)組件需要借助useState

用法:

const [stateName, setStateName] = React.useState(stateValue);

以下代碼實(shí)現(xiàn)了一秒后頁面上的文字變化:

function MyComponent() {
  const [msg, setMsg] = React.useState("Hello React!");
  setTimeout(() => setMsg("Hello Hooks!"), 1000);
  return <p>{msg}</p>;
}
ReactDOM.render(<MyComponent />, document.getElementById("app"));

效果:

2.2 useEffect

React hooks也提供了 api ,用于彌補(bǔ)函數(shù)組件沒有生命周期的缺陷。

用法:

useEffect(()=>{
    return destory
},dep)

useEffect 第一個(gè)參數(shù) 是一個(gè)函數(shù), 返回的 destory , destory 作為下一次callback執(zhí)行之前調(diào)用,用于清除上一次 回調(diào)函數(shù)產(chǎn)生的副作用。

第二個(gè)參數(shù)作為依賴項(xiàng),是一個(gè)數(shù)組,可以有多個(gè)依賴項(xiàng),依賴項(xiàng)改變,執(zhí)行上一次回調(diào)函數(shù)返回的 destory ,和執(zhí)行新的 effect 第一個(gè)參數(shù)。

對(duì)于 useEffect 執(zhí)行, React 處理邏輯是采用異步調(diào)用 ,對(duì)于每一個(gè) effect 的 callback, React 會(huì)向 setTimeout回調(diào)函數(shù)一樣,放入任務(wù)隊(duì)列,等到主線程任務(wù)完成,DOM 更新,js 執(zhí)行完成,視圖繪制完畢,才執(zhí)行。所以 effect 回調(diào)函數(shù)不會(huì)阻塞瀏覽器繪制視圖。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>useEffect</title>
    <script src="https://cdn.staticfile.org/react/16.8.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/16.8.0/umd/react-dom.development.js"></script>
    <!-- 生產(chǎn)環(huán)境中不建議使用 -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="text/babel">
      const Clock = (props) => {
        const [n, setN] = React.useState(0);
        function addNum() {
          setN(n + 1);
        }
        React.useEffect(() => {
          console.log(n);
        });
        return (
          <div>
            <p>現(xiàn)在的n是 {n} .</p>
            <button onClick={addNum}>n+1</button>
          </div>
        );
      };
      ReactDOM.render(<Clock />, document.getElementById("app"));
    </script>
  </body>
</html>

  • 組合 componentDidMount componentDidUpdate

當(dāng)useEffect沒有第二個(gè)參數(shù)時(shí),組件的初始化和更新都會(huì)執(zhí)行。

 useEffect(() => {
    //doSomething
  }, [])
  • componentDidMount

useEffect的第二個(gè)參數(shù)為一個(gè)空數(shù)組,初始化調(diào)用一次之后不再執(zhí)行,相當(dāng)于componentDidMount。

 useEffect(() => {
    //doSomething
  }, [])
  • 組合 componentDidMount componentWillUnmount

useEffect返回一個(gè)函數(shù),這個(gè)函數(shù)會(huì)在組件卸載時(shí)執(zhí)行。

useEffect(() => {
    return () => {
    	...
    };
  }, []);

2.3 useMemo

它返回的是一個(gè) memoized 值,僅會(huì)在某個(gè)依賴項(xiàng)改變時(shí)才重新計(jì)算 memoized 值。這種優(yōu)化有助于避免在每次渲染時(shí)都進(jìn)行高開銷的計(jì)算。我們可以拿 vue 里面的 計(jì)算屬性computed和它做一個(gè)對(duì)比,都是返回基于依賴重新計(jì)算的值。

const cacheSomething = useMemo(create,deps)

① create:第一個(gè)參數(shù)為一個(gè)函數(shù),函數(shù)的返回值作為緩存值。

② deps: 第二個(gè)參數(shù)為一個(gè)數(shù)組,存放當(dāng)前 useMemo 的依賴項(xiàng),在函數(shù)組件下一次執(zhí)行的時(shí)候,會(huì)對(duì)比 deps 依賴項(xiàng)里面的狀態(tài),是否有改變,如果有改變重新執(zhí)行 create ,得到新的緩存值。

③ acheSomething:返回值,執(zhí)行 create 的返回值。如果 deps 中有依賴項(xiàng)改變,返回的重新執(zhí)行 create 產(chǎn)生的值,否則取上一次緩存值。

function MyComponent() {
	 const [n, setN] = React.useState(0);
	 const [t, setT] = React.useState(0);
	 const getT = () => {
	   console.log("調(diào)用getT獲取T!");
	    return t;
	  };
	 return (
	   <div>
	     <p>n: {n}</p>
	     <p>t: {getT}</p>
	     <button onClick={() => setN(n + 1)}>n + 1</button>
	     <br />
	     <button onClick={() => setT(t + 1)}>t + 1</button>
	   </div>
	 );
}
ReactDOM.render(<MyComponent />, document.getElementById("app"));

此時(shí)無論改變n還是t,都會(huì)導(dǎo)致getT函數(shù)被調(diào)用,但是事實(shí)上,在n改變時(shí),并不需要重新調(diào)用一遍getT函數(shù)。

我們使用useMemo來實(shí)現(xiàn)僅t改變,getT才重新運(yùn)行。

      function MyComponent() {
        const [n, setN] = React.useState(0);
        const [t, setT] = React.useState(0);
        const getT = React.useMemo(() => {
          console.log("調(diào)用getT獲取T!");
          return t;
        }, [t]);
        return (
          <div>
            <p>n: {n}</p>
            <p>t: {getT}</p>
            <button onClick={() => setN(n + 1)}>n + 1</button>
            <br />
            <button onClick={() => setT(t + 1)}>t + 1</button>
          </div>
        );

注意,此時(shí)getT不在是一個(gè)函數(shù),而是useMemo回調(diào)函數(shù)返回的值,所以在頁面上直接使用getT即可。

2.4 useCallback

useMemo 和 useCallback 接收的參數(shù)都是一樣,都是在其依賴項(xiàng)發(fā)生變化后才執(zhí)行,都是返回緩存的值。

區(qū)別在于 useMemo 返回的是函數(shù)運(yùn)行的結(jié)果,useCallback 返回的是函數(shù),這個(gè)回調(diào)函數(shù)是經(jīng)過處理后的也就是說父組件傳遞一個(gè)函數(shù)給子組件的時(shí)候。

由于是無狀態(tài)組件每一次都會(huì)重新生成新的 props 函數(shù),這樣就使得每一次傳遞給子組件的函數(shù)都發(fā)生了變化,這時(shí)候就會(huì)觸發(fā)子組件的更新,這些更新是沒有必要的,此時(shí)我們就可以通過 usecallback 來處理此函數(shù),然后作為 props 傳遞給子組件。

我們依然利用useMemo的例子:

可以看到,此時(shí)getT是一個(gè)函數(shù),并不是一個(gè)值,這也是useMemo和useCallback的區(qū)別,即返回結(jié)果不同。

2.5 useContext

可以使用 useContext ,來獲取父級(jí)組件傳遞過來的 context 值(上下文),這個(gè)當(dāng)前值就是最近的父級(jí)組件 Provider 設(shè)置的 value 值,useContext 參數(shù)一般是由 createContext 方式創(chuàng)建的 ,也可以父級(jí)上下文 context 傳遞的 ( 參數(shù)為 context )。

創(chuàng)建context:

const context = createContext();

使用context:

const contextValue = useContext(context)
const Context = React.createContext();
const ChildComponent01 = () => {
  const c = React.useContext(Context);
  return (
    <div>
      <p>/* 用useContext方式 */</p>
      My name is {c.name}, I'm {c.age}.
    </div>
  );
};
const ChildComponent02 = () => {
  return (
    <Context.Consumer>
      {(value) => (
        <div>
          <p>/* 用Context.Consumer 方式 */</p>
          My name is {value.name}, I'm {value.age}.
        </div>
      )}
    </Context.Consumer>
  );
};
const MyComponent = () => {
  return (
    <div>
      <Context.Provider value={{ name: "yancy", age: 20 }}>
        <ChildComponent01 />
        <ChildComponent02 />
      </Context.Provider>
    </div>
  );
}
ReactDOM.render(<MyComponent />, document.getElementById("app"));

使用useContext可以避免使用props進(jìn)行傳參造成數(shù)據(jù)傳遞十分繁瑣和困難的問題。

2.6 useRef

在 React 數(shù)據(jù)流中,props 是父組件和子組件交互的唯一方式。要修改一個(gè)子組件,必須使用新的 props 去重新渲染它。而 refs 提供了另一種方式,允許我們?cè)?React 典型數(shù)據(jù)流之外,去操作 DOM 元素和類組件的實(shí)例。

useRef 返回一個(gè)對(duì)象,返回的ref對(duì)象在組件的整個(gè)生命周期保持不變。

最常用的ref是兩種對(duì)象
用法1: 引入DOM(或者組件,組件必須是類組件)元素
用飯2: 保存一個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)在組件的整個(gè)生命周期中可以保存

基于組件的框架(react、vue)是不推薦直接操作dom元素的,例如使用document.getElementById(“”)來獲取元素,react提供了useRef來使我們能夠獲取綁定的dom元素。

const MyComponent = () => {
        const titleRef = React.useRef();
        const inputRef = React.useRef();
        function changeDOM() {
          titleRef.current.innerHTML = "useRef";
          inputRef.current.focus();
        }
        return (
          <div>
            <h2 ref={titleRef}> Hello World </h2>
            <input ref={inputRef} type="text" />
            <button onClick={(e) => changeDOM()}>修改DOM</button>
          </div>
        );
      };
      ReactDOM.render(<MyComponent />, document.getElementById("app"));

還可以利用useRef配合useEffect來獲取上一次的state:

const MyComponent = () => {
  const [count, setCount] = React.useState(0);
  const numRef = React.useRef(count);
  React.useEffect(() => {
    numRef.current = count;
  }, [count]);
  return (
    <div>
      <h2>count 上一次的值: {numRef.current}</h2>
      <h2>count 這一次的值: {count}</h2>
      <button onClick={(e) => setCount(count + 1)}>count + 1</button>
    </div>
  );
};
ReactDOM.render(<MyComponent />, document.getElementById("app"));

三、總結(jié)

在 react 的 class組件寫法中,隨處可見各種各樣的 .bind(this)。(甚至官方文檔里也有專門的章節(jié)描述了“為什么綁定是必要的?”這一問題)

而在函數(shù)組件中通過使用hooks,可以完美地代替類組件,并且?guī)缀醪挥藐P(guān)心this的指向問題。

Vue3.2的組合式api也引入了hooks,可以看到hooks是前端框架發(fā)展的趨勢(shì),是一個(gè)組件的靈魂所在。

到此這篇關(guān)于React組件學(xué)習(xí)之Hooks使用的文章就介紹到這了,更多相關(guān)React Hooks內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React服務(wù)端渲染原理解析與實(shí)踐

    React服務(wù)端渲染原理解析與實(shí)踐

    這篇文章主要介紹了React服務(wù)端渲染原理解析與實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 2022最新前端常見react面試題合集

    2022最新前端常見react面試題合集

    這篇文章主要介紹了前端常見react面試題合集,介紹了React?Fiber的簡(jiǎn)介及fetch封裝代碼,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • 為react組件庫添加typescript類型提示的方法

    為react組件庫添加typescript類型提示的方法

    這篇文章主要介紹了為react組件庫添加typescript類型提示,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • React Router v4 入坑指南(小結(jié))

    React Router v4 入坑指南(小結(jié))

    這篇文章主要介紹了React Router v4 入坑指南(小結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • React動(dòng)畫實(shí)現(xiàn)方案Framer Motion讓頁面自己動(dòng)起來

    React動(dòng)畫實(shí)現(xiàn)方案Framer Motion讓頁面自己動(dòng)起來

    這篇文章主要為大家介紹了React動(dòng)畫實(shí)現(xiàn)方案Framer Motion讓頁面自己動(dòng)起來,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • React學(xué)習(xí)筆記之高階組件應(yīng)用

    React學(xué)習(xí)筆記之高階組件應(yīng)用

    這篇文章主要介紹了React 高階組件應(yīng)用,詳細(xì)的介紹了什么是React高階組件和具體使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • react性能優(yōu)化useMemo與useCallback使用對(duì)比詳解

    react性能優(yōu)化useMemo與useCallback使用對(duì)比詳解

    這篇文章主要為大家介紹了react性能優(yōu)化useMemo與useCallback使用對(duì)比詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • webpack+react+antd腳手架優(yōu)化的方法

    webpack+react+antd腳手架優(yōu)化的方法

    本篇文章主要介紹了webpack+react+antd腳手架優(yōu)化的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • react滾動(dòng)加載useInfiniteScroll?詳解

    react滾動(dòng)加載useInfiniteScroll?詳解

    使用useInfiniteScroll?hook可以處理檢測(cè)用戶何時(shí)滾動(dòng)到頁面底部的邏輯,并觸發(fā)回調(diào)函數(shù)以加載更多數(shù)據(jù),它還提供了一種簡(jiǎn)單的方法來管理加載和錯(cuò)誤消息的狀態(tài),今天通過實(shí)例代碼介紹下react滾動(dòng)加載useInfiniteScroll?相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2023-09-09
  • React18+TS通用后臺(tái)管理系統(tǒng)解決方案落地實(shí)戰(zhàn)示例

    React18+TS通用后臺(tái)管理系統(tǒng)解決方案落地實(shí)戰(zhàn)示例

    這篇文章主要為大家介紹了React18+TS通用后臺(tái)管理系統(tǒng)解決方案落地實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08

最新評(píng)論