中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解React hooks的渲染邏輯

發布時間:2021-11-04 15:37:55 來源:億速云 閱讀:138 作者:iii 欄目:web開發

這篇文章主要介紹“怎么理解React hooks的渲染邏輯”,在日常操作中,相信很多人在怎么理解React hooks的渲染邏輯問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么理解React hooks的渲染邏輯”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

由于項目環境比較復雜,如果是純class組件,那么就是component、pureComponent、shouldComponentUpdate之類的控制一下是否重新渲染,但是hooks似乎更多場景,接下來一一攻破。

  •  場景一 ,父組件使用hooks,子組件使用class Component

父組件

export default function Test() {      const [state, setState] = useState({ a: 1, b: 1, c: 1 });      const [value, setValue] = useState(11);      return (          <div>              <div>                  state{state.a},{state.b}              </div>              <Button                  type="default"                  onClick={() => {                      //@ts-ignore                      setState({ a: 2, b: 1 });                      //@ts-ignore                      setState({ a: 2, b: 2 });                      console.log(state, 'state');                  }}              >                  測試              </Button>              <hr />              <div>value{value}</div>              <Button                  type="default"                  onClick={() => {                      setValue(value + 1);                  }}              >                  測試              </Button>              <Demo value={state} />          </div>      );  }

子組件

export default class App extends React.Component<Props> {      render() {          const { props } = this;          console.log('demo render');          return (              <div>                  {props.value.a},{props.value.b}              </div>          );      }  }

結果每次點擊圖中的測試按鈕,子組件Demo都會重新render:

怎么理解React hooks的渲染邏輯

總結:父組件(hook)每次更新,都會導出一個新的state和value對象,子組件肯定會更新(如果不做特殊處理)

  •  場景二,父組件使用hooks,子組件使用class PureComponent 

父組件代碼跟上面一樣,子組件使用PureComponent:

export default function Test() {      const [state, setState] = useState({ a: 1, b: 1, c: 1 });      const [value, setValue] = useState(11);      return (          <div>              <div>                  state{state.a},{state.b}              </div>              <Button                  type="default"                  onClick={() => {                      //@ts-ignore                      setState({ a: 2, b: 1 });                      //@ts-ignore                      setState({ a: 2, b: 2 });                      console.log(state, 'state');                  }}              >                  測試              </Button>              <hr />              <div>value{value}</div>              <Button                  type="default"                  onClick={() => {                      setValue(value + 1);                  }}              >                  測試              </Button>              <Demo value={state} />          </div>      );  }

子組件使用PureComponent:

export default class App extends React.PureComponent<Props> {      render() {          const { props } = this;          console.log('demo render');          return (              <div>                  {props.value.a},{props.value.b}              </div>          );      }  }

結果子組件依舊會每次都重新render:

怎么理解React hooks的渲染邏輯

總結:結論同上,確實是依賴的props改變了,因為父組件是hook模式,每次更新都是直接導出新的value和state.

  •  場景三,搞懂hook的setState跟class組件setState有什么不一樣

理論:class的setState,如果你傳入的是對象,那么就會被異步合并,如果傳入的是函數,那么就會立馬執行替換,而hook的setState是直接替換,那么setState在hook中是異步還是同步呢?

實踐:

組件A:

export default function Test() {      const [state, setState] = useState({ a: 1, b: 1, c: 1 });      const [value, setValue] = useState(11);      return (          <div>              <div>                  state{state.a},{state.b},{state.c}              </div>              <Button                  type="default"                  onClick={() => {                      //@ts-ignore                      setState({ a: 2 });                      //@ts-ignore                      setState({ b: 2 });                      console.log(state, 'state');                  }}              >                  測試              </Button>              <hr />              <div>value{value}</div>              <Button                  type="default"                  onClick={() => {                      setValue(value + 1);                  }}              >                  測試              </Button>              <Demo value={state} />          </div>      );  }

我將setState里兩次分別設置了state的值為{a:2},{b:2},那么是合并,那么我最終得到state應該是{a:2,b:2,c:1},如果是替換,那么最后得到的state是{b:2}

結果:

怎么理解React hooks的渲染邏輯

點擊測試按鈕后,state變成了{b:2},整個value被替換成了{b:2}

結論:hook的setState是直接替換,而不是合并

  •  場景四 , 父組件使用class,子組件使用hook

  父組件:

export default class App extends React.PureComponent {      state = {          count: 1,      };      onClick = () => {          const { count } = this.state;          this.setState({              count: count + 1,          });      };      render() {          const { count } = this.state;          console.log('father render');          return (              <div>                  <Demo count={count} />                  <Button onClick={this.onClick}>測試</Button>              </div>          );      }  }

子組件:

interface Props {      count: number;  }  export default function App(props: Props) {      console.log(props, 'props');      return <div>{props.count}</div>;  }

邏輯:父組件(class組件)調用setState,刷新自身,然后傳遞給hooks子組件,然后自組件重新調用,更新

怎么理解React hooks的渲染邏輯

  •  場景五

但是我此時需要想實現一個class 組件的 PureComponent一樣的效果,需要用到React.memo

修改父組件代碼為:

export default class App extends React.PureComponent {      state = {          count: 1,          value: 1,      };      onClick = () => {          const { value } = this.state;          this.setState({              count: value + 1,          });      };      render() {          const { count, value } = this.state;          console.log('father render');          return (              <div>                  <Demo count={count} />                  {value}                  <Button onClick={this.onClick}>測試</Button>              </div>          );      }  }

子組件加入memo,代碼修改為:

import React, { useState, memo } from 'react';  interface Props {      count: number;  }  function App(props: Props) {      console.log(props, 'props');      return <div>{props.count}</div>;  }  export default memo(App);

此時邏輯:class組件改變了自身的state,自己刷新自己,由上而下,傳遞了一個沒有變化的props給hooks組件,hooks組件使用了memo包裹自己。

結果:

怎么理解React hooks的渲染邏輯

我們使用了memo實現了PureComponent的效果,淺比較了一次

  •  場景六,hook,setState每次都是相同的值 

export default class App extends React.PureComponent {      state = {          count: 1,          value: 1,      };      onClick = () => {          const { value } = this.state;          this.setState({              value:   1,          });      };      render() {          const { count, value } = this.state;          console.log('father render');          return (              <div>                  <Demo count={count} />                  {value}                  <Button onClick={this.onClick}>測試</Button>              </div>          );      }  }

結果:由于每次設置的值都是一樣的(都是1),hooks不會更新,同class

  •  場景七,父組件和子組件都使用hook

父組件傳入count給子組件

export default function Father() {      const [count, setCount] = useState(1);      const [value, setValue] = useState(1);      console.log('father render')      return (          <div>              <Demo count={count} />              <div>value{value}</div>              <Button                  onClick={() => {                      setValue(value + 1);                  }}              >                  測試              </Button>          </div>      );  }

子組件使用count

export default function App(props: Props) {      console.log(props, 'props');      return <div>{props.count}</div>;  }

結果:每次點擊測試,都會導致子組件重新render

怎么理解React hooks的渲染邏輯

子組件加入memo

function App(props: Props) {      console.log(props, 'props');      return <div>{props.count}</div>;  }  export default memo(App);

結果:

怎么理解React hooks的渲染邏輯

子組件并沒有觸發更新

這里跟第一個案例class的PureComponent不一樣,第一個案例class的PureComponent子組件此時會重新render,是因為父組件hooks確實每次更新都會導出新的value和state。這里是調用了一次,設置的都是相同的state.所以此時不更新

  •  場景八,父組件hook,子組件hook,使用useCallback緩存函數

父組件:

export default function App() {    const [count1, setCount1] = useState(0);    const [count2, setCount2] = useState(0);   const handleClickButton1 = () => {      setCount1(count1 + 1);    };    const handleClickButton2 = useCallback(() => {      setCount2(count2 + 1);    }, [count2]);     return (      <div>        <div>          <Button onClickButton={handleClickButton1}>Button1</Button>        </div>        <div>          <Button onClickButton={handleClickButton2}>Button2</Button>        </div>      </div>    );  }

子組件:

import React from 'react';  const Button = (props: any) => {     const { onClickButton, children } = props;      return (          <>              <button onClick={onClickButton}>{children}</button>              <span>{Math.random()}</span>          </>      );  };  export default React.memo(Button);

結果:雖然我們使用了memo.但是點擊demo1,只有demo1后面的數字改變了,demo2沒有改變,點擊demo2,兩個數字都改變了。

那么我們不使用useCallback看看

父組件修改代碼,去掉useCallback

export default function App() {      const [count1, setCount1] = useState(0);      const [count2, setCount2] = useState(0);      const handleClickButton1 = () => {          setCount1(count1 + 1);      };      const handleClickButton2 = () => {          setCount2(count2+ 1);      };      return (          <div>              <div>                  <Demo onClickButton={handleClickButton1}>Demo1</Demo>              </div>              <div>                  <Demo onClickButton={handleClickButton2}>Demo</Demo>              </div>          </div>      );  }

子組件代碼不變,結果此時每次都會兩個數字都會跟著變。

怎么理解React hooks的渲染邏輯

官方對useCallback的解釋:

就是返回一個函數,只有在依賴項發生變化的時候才會更新(返回一個新的函數)

結論:

我們聲明的 handleClickButton1 是直接定義了一個方法,這也就導致只要是父組件重新渲染(狀態或者props更新)就會導致這里聲明出一個新的方法,新的方法和舊的方法盡管長的一樣,但是依舊是兩個不同的對象,React.memo 對比后發現對象 props 改變,就重新渲染了。

const a =()=>{}  const b =()=>{}  a===b //false

這個道理大家都懂,不解釋了

  •  場景九,去掉依賴數組中的count2字段 

import React, { useState, useCallback } from 'react';  import Demo from './Demo';  export default function App() {    const [count2, setCount2] = useState(0);    const handleClickButton2 = useCallback(() => {      setCount2(count2 + 1);    }, []);    return (      <Demo         count={count2}        onClickButton={handleClickButton2}      >測試</Demo>    );  }

這樣count2的值永遠都是0,那么這個組件就不會重導出setCount2這個方法,handleClickButton2這個函數永遠不會變化,Button只會更新一次,就是Demo組件接受到的props從0到1到的時候.繼續點擊,count2也是0,但是props有一次從0-1的過程導致Demo子組件被更新,不過count2始終是0,這非常關鍵

  •  場景十,使用useMemo,緩存對象,達到useCallback的效果

使用前

export default function App() {      const [count, setCount] = useState(0);      const [value, setValue] = useState(0);      const userInfo = {          age: count,          name: 'Jace',      };      return (          <div>              <div>                  <Demo userInfo={userInfo} />              </div>              <div>                  {value}                  <Button                      onClick={() => {                          setValue(value + 1);                      }}                  ></Button>              </div>          </div>      );  }

子組件使用了memo,沒有依賴value,只是依賴了count.

但是結果每次父組件修改了value的值后,雖然子組件沒有依賴value,而且使用了memo包裹,還是每次都重新渲染了

怎么理解React hooks的渲染邏輯

import React from 'react';  const Button = (props: any) => {      const { userInfo } = props;      console.log('sub render');      return (          <>              <span>{userInfo.count}</span>          </>      );  };  export default React.memo(Button);

使用后useMemo

const [count, setCount] = useState(0);  const obj = useMemo(() => {    return {      name: "Peter",      age: count    };  }, [count]);  return <Demo obj={obj}>

很明顯,第一種方式,如果每次hook組件更新,那么hook就會導出一個新的count,const 就會聲明一個新的obj對象,即使用了memo包裹,也會被認為是一個新的對象。

看看第二種的結果:

怎么理解React hooks的渲染邏輯

父組件更新,沒有再影響到子組件了。

到此,關于“怎么理解React hooks的渲染邏輯”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泰宁县| 白朗县| 清涧县| 乌兰浩特市| 岐山县| 卫辉市| 漳浦县| 息烽县| 抚顺市| 平乐县| 富川| 蚌埠市| 清新县| 军事| 额济纳旗| 南阳市| 高要市| 麻栗坡县| 周至县| 达尔| 积石山| 东乡县| 松潘县| 合阳县| 泾川县| 中方县| 雷山县| 云梦县| 金门县| 科技| 康乐县| 即墨市| 辽宁省| 甘德县| 仙游县| 临潭县| 涪陵区| 河间市| 湘阴县| 三都| 开化县|