返回顶部
首页 > 资讯 > 前端开发 > node.js >怎么理解React hooks的渲染逻辑
  • 270
分享到

怎么理解React hooks的渲染逻辑

2024-04-02 19:04:59 270人浏览 薄情痞子
摘要

这篇文章主要介绍“怎么理解React hooks的渲染逻辑”,在日常操作中,相信很多人在怎么理解React hooks的渲染逻辑问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”

这篇文章主要介绍“怎么理解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的渲染逻辑”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: 怎么理解React hooks的渲染逻辑

本文链接: https://lsjlt.com/news/85096.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么理解React hooks的渲染逻辑
    这篇文章主要介绍“怎么理解React hooks的渲染逻辑”,在日常操作中,相信很多人在怎么理解React hooks的渲染逻辑问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • Hybris CommerceUI tag的渲染逻辑是什么
    这篇文章主要介绍“Hybris CommerceUI tag的渲染逻辑是什么”,在日常操作中,相信很多人在Hybris CommerceUI tag的渲染逻辑是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-06-04
  • react异步渲染问题怎么解决
    在React中,可以使用异步渲染来优化性能并提升用户体验。有几种方式可以解决React异步渲染问题:1. 使用React.lazy和...
    99+
    2023-08-19
    react
  • 怎么使用React虚拟渲染实现多个图表渲染
    今天小编给大家分享一下怎么使用React虚拟渲染实现多个图表渲染的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。需求每行渲染3...
    99+
    2023-07-02
  • React中怎么实现条件渲染
    今天就跟大家聊聊有关React中怎么实现条件渲染,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1. if-else我们可以将 if-else 条件逻...
    99+
    2024-04-02
  • React服务器端渲染怎么用
    这篇文章给大家分享的是有关React服务器端渲染怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。React 提供了两个方法 renderToString 和 renderTo...
    99+
    2024-04-02
  • react怎么让子组件不渲染
    本教程操作环境:Windows10系统、react18.0.0版、Dell G3电脑。react怎么让子组件不渲染?React 父组件重新渲染,子组件不需要渲染的三种性能优化方式(PureComponent,memo,shouldCompo...
    99+
    2023-05-14
    组件 React
  • react中usestate改变值不渲染怎么解决
    这篇文章主要介绍“react中usestate改变值不渲染怎么解决”,在日常操作中,相信很多人在react中usestate改变值不渲染怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,...
    99+
    2024-04-02
  • react条件渲染指的是什么
    这篇文章主要介绍“react条件渲染指的是什么”,在日常操作中,相信很多人在react条件渲染指的是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”react条件渲染指的是...
    99+
    2024-04-02
  • 解决react组件渲染两次的问题
    目录react组件渲染两次react总结之避免不必要的重复渲染类组件PureComponent使用插件seamless-immutable使用插件pure-render-decora...
    99+
    2022-11-13
    react组件渲染 react渲染两次 react组件
  • react有数据但渲染不上怎么办
    本教程操作环境:Windows10系统、react18.0.0版、Dell G3电脑。react有数据但渲染不上怎么办?react 获取后台数据渲染页面不显示问题描述:想要的结果:在一个 react 的 Component 获取后台的数据并...
    99+
    2023-05-14
    React 渲染
  • 怎么学习React Hooks原理
    这篇文章主要介绍“怎么学习React Hooks原理”,在日常操作中,相信很多人在怎么学习React Hooks原理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么学习Re...
    99+
    2024-04-02
  • React中immutable的UI组件渲染性能详解
    目录引言UI组件渲染性能方案一:shallow compare方案二:直接对前后的对象进行deepCompare总结:引言 react 一直遵循UI = fn(state) 的原则,...
    99+
    2023-05-16
    React immutable UI组件渲染 React UI组件渲染
  • 使用React怎么对服务端进行渲染
    使用React怎么对服务端进行渲染?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。服务器端编写 React 组件如果是客户端渲染,浏览器首先会向浏览器发送请求,服...
    99+
    2023-06-06
  • React服务端渲染和同构怎么实现
    这篇文章主要讲解了“React服务端渲染和同构怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React服务端渲染和同构怎么实现”吧!背景第一阶段很久以前, 一个网站的开发还是前端和服...
    99+
    2023-06-30
  • React Hooks的原理是什么
    这篇文章主要讲解了“React Hooks的原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React Hooks的原理是什么”吧!0x0...
    99+
    2024-04-02
  • React Hooks与setInterval的坑怎么解决
    这篇文章主要讲解了“React Hooks与setInterval的坑怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React Hooks与setInterval...
    99+
    2023-06-30
  • react中useState改变值不渲染的解决方式
    目录react中useState改变值不渲染解决的办法react踩坑 useState的两次渲染检测意外的副作用react中useState改变值不渲染 React中默认浅监听,当S...
    99+
    2022-12-03
    react useState useState改变值不渲染 useState不渲染
  • React中怎么实现组件逻辑复用
    React中怎么实现组件逻辑复用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. MixinsMixins 事实上是 Rea...
    99+
    2024-04-02
  • React中的Hooks进阶理解教程
    目录Hooks进阶useState - 回调函数的参数useEffect - 清理副作用useEffect - 发送网络请求useRefuseContextHooks进阶 useSt...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作