React基础知识点总结--4

本文深入探讨React原理,包括setState()的异步更新、JSX的转化、组件更新与优化,以及虚拟DOM和Diff算法。同时,介绍了React路由的基础,如路由的执行过程、编程式导航、默认路由和匹配模式,帮助开发者理解React路由的工作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

五、React原理揭秘

目标

◆ 能够知道setState()更新数据是异步的
◆ 能够知道JSX语法的转化过程
◆ 能够说出React组件的更新机制
◆ 能够对组件进行性能优化
◆ 能够说出虚拟DOM和Diff算法

目录

◆ setState() 的说明
◆ JSX语法的转化过程
◆ 组件更新机制
◆ 组件性能优化
◆ 虚拟DOM和Diff算法

1.setState() 的说明

1.1 更新数据

setState()异步更新数据的
● 注意:使用该语法时,后面的setState()不要依赖于前面的setState()
● 可以多次调用setState() , 只会触发一次重新渲染

1.2推荐语法

● 推荐:使用**setState((state, props) => {})**语法
● 参数state :表示最新的state
● 参数props :表示最新的props

1.3第二个参数

● 场景:在状态更新(页面完成重新渲染)后应即执行某个操作
● 语法:setState(updater[,callback])

2. JSX语法的转化过程

● JSX仅仅是createElement(方法的语法糖(简化语法)

● JSX语法被@babel/preset-react插件编译为createElement()方法

● React元素:是一个对象,用来描述你希望在屏幕上看到的内容

3. 组件更新机制

setState()的两个作用: 1. 修改state 2.更新组件(UI )

● 过程:父组件重新渲染时,也会重新渲染子组件。但只会渲染当前组件子树(当前组件及其所有子组件)

4.组件性能优化

4.1减轻state

减轻state :只存储跟组件渲染相关的数据(比如: count/列表数据/ loading等)

● 注意:不用做渲染的数据不要放在state中,比如定时器id等

● 对于这种需要在多个方法中用到的数据,应该放在this中

4.2 避免不必要的重新渲染

● 组件更新机制:父组件更新会引|起子组件也被更新,这种思路很清晰
● 问题:子组件没有任何变化时也会重新渲染
● 如何避免不必要的重新渲染呢?
● 解决方式:使用钩子函数shouldComponentUpdate(nextProps, nextState)
● 作用:通过返回值决定该组件是否重新渲染,返回true表示重新渲染, false表示不重新渲染
● 触发时机:更新阶段的钩子函数,组件重新渲染前执行( shouldC omponentUpdate --> render )

● 案例:随机数

4.3 纯组件

● 纯组件: PureComponent与React.Component功能相似
● 区别: PureComponent内部自动实现了shouldComponentUpdate钩子,不需要手动比较
● 原理:纯组件内部通过分别对比前后两次props和state的值,来决定是否重新渲染组件

● 说明:纯组件内部的对比是shallow compare (浅层对比)

● 对于值类型来说:比较两个值是否相同(直接赋值即可,没有坑)

● 对于引用类型来说:只比较对象的引用(她址)是否相同

● 注意: state或props中属性值为引用类型时,应该创建新数据,不要直接修改原数据! ( 示例)

5. 虚拟DOM和Diff算法

● React 更新视图的思想是:只要state变化就重新渲染视图
● 特点:思路非常清晰
● 问题:组件中只有一一个 DOM元素需要更新时,也得把整个组件的内容重新渲染到页面中?不是
● 理想状态:部分更新,只更新变化的地方。
● 问题: React是如何做到部分更新的? 虚拟DOM配合Diff 算法

虚拟DOM :本质上就是一个JS对象,用来描述你希望在屏幕上看到的内容(UI)。

执行过程

  1. 初次渲染时, React会根据初始state ( Model) ,创建一 个虚拟DOM对象(树)

  2. 根据虚拟DOM生成真正的DOM ,渲染到页面中。

  3. 当数据变化后( setState() ,重新根据新的数据,创建新的虚拟DOM对象(树)。

  4. 与上-次得到的虚拟DOM对象,使用Diff算法对比(找不同) ,得到需要更新的内容。

  5. 最终, React只将变化的内容更新( patch )到DOM中,重新渲染到页面。

代码演示

● 组件render()调用后,根据状态JSX结构生成虚拟DOM对象
● 示例中,只更新p元素的文本节点内容

6. 总结–React原理揭秘

  1. 工作角度:应用第一,原理第二。

  2. 原理有助于更好地理解React的自身运行机制。

  3. setState()异步更新数据。

  4. 父组件更新导致子组件更新,纯组件提升性能。

  5. 思路清晰简单为前提,虚拟DOM和Diff保效率。

  6. 虚拟DOM → state + JSX。

  7. 虚拟DOM的真正价值从来都不是性能。

  8. 虚拟DOM最大价值:让React脱离了浏览器的束缚(虚拟DOM:JS的一个对象)

六、React路由基础

目标

◆ 能够说出React路由的作用
◆ 能够掌握react-router-dom的基本使用
◆ 能够使用编程式导航跳转路由
◆ 能够知道React路由的匹配模式

目录

◆ React路由介绍
◆ 路由的基本使用
◆ 路由的执行过程
◆ 编程式导航
◆ 默认路由
◆ 匹配模式

1. React路由介绍

​ 现代的前端应用大多都是SPA (单页应用程序) ,也就是只有一一个HTML页面的应用程序。因为它的用户体验更好、对服务器的压力更小,所以更受欢迎。为了有效的使用单个页面来管理原来多页面的功能,前端路由应运而生。
● 前端路由的功能:让用户从一一个视图(页面)导航到另-一个视图(页面)
● 前端路由是一套映射规则,在React中,是URL路径组件的对应关系
● 使用React路由简单来说,就是配置路径组件(配对)

2. React路由的基本使用

2.1 使用步骤

  1. 安装: yarn add react- router-dom/npm i react-router-dom

  2. 导入路由的三个核心组件: Router / Route / Link

    import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
    
  3. 使用Router组件包裹整个应用(重要)

    <Router>
    	<div className="App">
    	// ... 省略页面内容
    	</div>
    </Router>
    
  4. 使用Link组件作为导航菜单(路由入口)

    <Link to="/first">页面一</Link>
    
  5. 使用Route组件配置路由规则和要展示的组件(路由出口)

    const First = () => <p>页面一的页面内容</p>
    <Router>
    	<div className="App">
    		<Link to="/first">页面一</Link>
    		<Route path="/first" component={First}></Route>
    	</div>
    </Router>
    
  6. 总代码

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
    
    const First = () =>(<p>页面一内容</p>)
    const App = ()=>(
      <Router>
        <div>
          <h1>路由页面一</h1>
          <Link to="/first">页面一</Link>
          <Route path="/first" component={First}></Route>
        </div>
      </Router>
    )
    
    ReactDOM.render(<App/>,document.getElementById('root'))
    

2.2 常用组件说明

● Router组件:包裹整个应用,一个React应用只需要使用一次
● 两种常用Router : HashRouter和BrowserRouter
● HashRouter :使用URL的哈希值实现(localhost:3000/#/first )
● (推荐) BrowserRouter :使用H5的history API实现(localhost:3000/first )

● Link 组件:用于指定导航链接(a标签)

// to属性:浏览器地址栏中的pathname (location.pathname)
<Link to="/first">页面一</Link>

● Route组件:指定路由展示组件相关信息

// path属性: 路由规则
// component属性: 展示的组件
// Route组件写在哪,渲染出来的组件就展示在哪
<Route path="/first" component={First}></Route>

3. 路由的执行过程

  1. 点击Link组件( a标签) ,修改了浏览器地址栏中的url。
  2. React 路由监听到地址栏url的变化。
  3. React 路由内部遍历所有Route组件,使用路由规则( path )与pathname进行匹配。
  4. 当路由规则( path )能够匹配地址栏中的pathname时,就展示该Route组件的内容。

4. 编程式导航

● 场景:点击登录按钮,登录成功后,通过代码跳转到后台首页,如何实现?
● 编程式导航:通过JS代码来实现页面跳转
● history是React路由提供的,用于获取浏览器历史记录的相关信息
push(path) :跳转到某个页面,参数path表示要跳转的路径

go(n) :前进或后退到某个页面,参数n表示前进或后退页面数量(比如: -1表示后退到上一页)

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

class Login extends React.Component{
  handleLogin=()=>{
    this.props.history.push('/home')
  }
  render(){
    return(
      <div>
        <h2>登录页面</h2>
        <button onClick={this.handleLogin}>登录</button>
      </div>
    )
  }
}
const Home =(props)=>{
  const handleBack =()=>{
    props.history.go(-1)
  }
  return(
    <div>
      <h2>首页</h2>
      <button onClick={handleBack}>去登录页</button>
    </div>
  )
}

class App extends React.Component{
  render(){
    return(
      <Router>
        <div>
        <h1>编程式导航</h1>
        <Link to="/login">去登录</Link>
        <Route path="/login" component={Login}></Route>
        <Route path="/home" component={Home}></Route>
      </div>
      </Router>
    )
  }
}
ReactDOM.render(<App/>,document.getElementById('root'))

5. 默认路由

● 问题:现在的路由都是点击导航菜单后展示的,如何在进入页面的时候就展示呢?
● 默认路由:表示进入页面时就会匹配的路由
● 默认路由path为: /

<Route path="/" component={Home} />

6. 匹配模式

6.1 模糊匹配

● 问题:当Link组件的to属性值为"/login"时,为什么默认路由也被匹配成功?
● 默认情况下, React路由是模糊匹配模式
● 模糊匹配规则:只要pathname以path开头就会匹配成功

<Link to="/login">登录页面</Link>
<Route path="/" component={Home} />匹配成功

● path代表Route组件的path属性

● pathname代表Link组件的to属性(也就是location.pathname)

6.2 精确匹配

● 问题:默认路由任何情况下都会展示,如何避免这种问题?
● 给Route组件添加exact属性,让其变为精确匹配模式
● 精确匹配:只有当pathpathname完全匹配时才会展示该路由

// 此时,该组件只能匹配pathname="/" 这一种情况
<Route exact path="/" component=. . . />

推荐: 给默认路由添加exact属性

7. 总结–React路由基础

  1. React路由可以有效的管理多个视图(组件)实现SPA

  2. Router组件包裹整个应用 ,只需要使用- -次

  3. Link组件是入口 , Route组件是出口

  4. 通过props.history实现编程式导航

  5. 默认模糊匹配,添加exact变精确匹配

  6. React路由的一切都是组件,可以像思考组件一样思考路由

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值