React入门

安装

​​​​​​​​​​​​​​​​​​​​​​​​​​​​懂王的React说明文档

环境安装

复制代码
npm config set registry https://registry.npmmirror.com

环境查看

复制代码
npm config get registry

安装React运行环境

复制代码
npx create-react-app my-app
cd my-app
npm start

入口文件

.

严格模式的作用

  1. 不安全的生命周期方法:某些生命周期方法在未来的React版本中将被弃用。严格模式会警告这些不安全的方法的使用。

  2. 使用过时或遗留的API:严格模式会警告使用过时或遗留的API。

  3. 意外的副作用:严格模式可以帮助你发现组件中可能的意外副作用。

  4. 与旧版本React不兼容的代码:严格模式会警告你的代码中可能与未来版本的React不兼容的部分

React和ReactDom两个包分别有什么作用?

  1. react:这是React库的核心。它定义了React组件的创建和生命周期方法,以及React元素的概念。你可以将其视为React的"引擎"。

  2. react-dom:这个库提供了在浏览器环境中使用React的方法,例如将React组件渲染到DOM中,或者在DOM中触发React组件的更新。你可以将其视为React的"驱动程序"。

创建第一个React组件

babeljs

JSX语法,需要经过编译,babel

React创建组件有两种方式

  1. Class (已被官方推荐废弃,但是需要了解学习,为函数式组件做铺垫)

  2. Fuction纯函数 (后续都会用这种方式 hooks)

生命周期

componentDidMount

组件挂载时执行

static getDerivedStateFromProps(props, state)

如果你定义了 static getDerivedStateFromProps,React 会在初始挂载和后续更新时调用 render 之前调用它。它应该返回一个对象来更新 state,或者返回 null 就不更新任何内容。

  • props:组件即将用来渲染的下一个 props。

  • state:组件即将渲染的下一个 state。

getSnapshotBeforeUpdate(prevProps, prevState)

如果你实现了 getSnapshotBeforeUpdate,React 会在 React 更新 DOM 之前时直接调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动的位置)。此生命周期方法返回的任何值都将作为参数传递给 componentDidUpdate

React官网

进入Hooks

  1. hooks真正的把react思想运用的淋漓尽致,彻底让你感觉写React=写JS

  2. hooks非常的神奇,一个钩子可以几乎实现Class类组件中的所有生命周期。

  3. hooks非常的奇葩,一个钩子居然可以实现Class类组件中的所有生命周期。

  4. hooks的学习难度指数级上升,因为它太灵活了!

  5. Vue居然不顾一切的要抄袭hooks???形似神不似,React才是祖师爷

useEffect

参数:

  1. 更新的回调函数

  2. 依赖项?

    a.[]

    import { useEffect } from 'react';

    function App() {

    useEffect(() => {
    console.log('useEffect执行')
    })

    return (

    hello hooks


    )
    }

执行时机:

  1. 组件初始化

  2. 组件更新之后执行(浏览器渲染更新完成之后)

当我传入依赖项 []

复制代码
  useEffect(() => {
    console.log('useEffect执行')
  },[])

执行时机:

  1. 组件初始化、挂载

当我们传入依赖项[a], 当传入多个依赖项的时候[a,b], a或者b发生变化都执行

  1. 初始化执行

  2. 依赖的状态发生变化会执行

当第二个依赖项不传的时候

  1. 初始化

  2. 组件内定义的state都是依赖项,发生变化就执行

useEffect返回的函数执行时机

  1. 组件卸载的时候

  2. 状态发生变化的时候执行

应用场景是什么?

useState

一个小案例

复制代码
import { useEffect, useState } from 'react';

import './App.css';

function App() {

  const [count, setCount] = useState(0) // [0, function(){}
  const [name, setName] = useState(() => {
    return '张三'
  }) // ['张三', function(){}

  // 第一个参数回调函数:组件初始化执行,组件更新之后会执行(dom更新完成)
  useEffect(() => {
    console.log('useEffect执行')

    return () => {
      console.log('组件卸载')
    }
  },[])

  function btn_click() {
    setCount((count) => {
      return count + 1
    })
    // count是几?  实际执行的结果是0。
    // react的组件状态更新是异步队列的,为了性能。
    console.log(count)
  }

  function btn_click2() {
    setName('李四')
  }

  return (
    <div>
      <h1>{count}</h1>
      <h1>{name}</h1>
      <button onClick={btn_click}>点我+1</button>
      <button onClick={btn_click2}>点我修改名字</button>
    </div>
  )
}

export default App;

useLayoutEffect

应用场景: 见第十一课demo

useMemo

它是用于react渲染过程 中的性能优化。

适用于: 父组件要进行更新,子组件的重新render计算量比较大,而且结果可以复用。就可以使用useMemo来提升父组件引起子组件不必要渲染的性能优化。

useCallback

对函数引用的缓存

React.memo

可以阻止父组件渲染引起的子组件(组件本身)更新。

name

age

old

useRef

可以获取组件中的dom实例

复制代码
import React, { useRef, useEffect } from 'react';

function Example() {
  const inputRef = useRef(null);
  console.log('inputRef', inputRef)

  useEffect(() => {

    console.log('inputRef useEffect中执行的', inputRef)

    inputRef.current.focus();
    // console.log('input', input)
  }, []);

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={() => inputRef.current.focus()}>Focus Input</button>
    </div>
  );
}

export default Example

useContext

跨组件传值

useTransition

演示React真正意义上比Vue厉害的地方。

用于性能,用于用户体验。

特性: 并发更新(fiber架构),16.8版本之后

并发更新

fiber架构

分片更新

异步更新

见面试题部分

useDefferedValue

use

canary特性,金丝雀特性

useDebugValue

这个调试工具需要在严格模式之下开启

useId

在React组件渲染过程中生成一个ID

这个ID是根据react组件树的位置相关,不是随机的。每次生成都一样

为什么不能用随机数?

因为有一种场景,Nodejs端去做React的服务端渲染(SSR 20K以上工程师要会的技术)。

需要确保Node端生成Id和前端(浏览器)一致。

useImperativeHandle

自定义ref, 通过forwardRefs转发出去

复制代码
import React, { forwardRef, useRef, useImperativeHandle } from 'react';

const CustomInput = forwardRef((props, ref) => {
  const inputRef = useRef();

  useImperativeHandle(ref, () => ({
    focusInput: () => {
      inputRef.current.focus();
    },
    getValue: () => {
      return inputRef.current.value;
    }
  }));

  return (
    <div>
      <input ref={inputRef} type="text" />
    </div>
  );
});

export default function App() {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focusInput();
  };

  const getValue = () => {
    const value = inputRef.current.getValue();
    console.log(value);
  };

  return (
    <div>
      <CustomInput ref={inputRef} />
      <button onClick={focusInput}>Focus Custom Input</button>
      <button onClick={getValue}>Get Value</button>
    </div>
  );
}

useInsertionEffect

useInsertionEffect 是为 CSS-in-JS 库的作者特意打造的。

如果你需要使用js插入style标签,请使用useInsertionEffect。

不要用其他,否则可能发生错误。

useSyncExternalStore

也是库的作者去使用的。

解决tearing,状态撕裂问题(react并发更新带来的问题)。

后续要学的:

路由 router

状态管理 redux

面试题

React和React-Dom的区别?为什么有两个库?

1.react:这是React库的核心。它定义了React组件的创建和生命周期方法,以及React元素的概念。你可以将其视为React的"引擎"。

2.react-dom:这个库提供了在浏览器环境中使用React的方法,例如将React组件渲染到DOM中,或者在DOM中触发React组件的更新。你可以将其视为React的"驱动程序"。

补充:

react-dom/client是浏览器渲染用的库,同理node端也有对应的库。

为什么有多个包,为了功能解耦,渲染有渲染专用的包,引擎就只负责引擎。

React是框架吗?

react的核心,其实是一个渲染的库。

React严格模式的作用?

1. 不安全的生命周期方法:某些生命周期方法在未来的React版本中将被弃用。严格模式会警告这些不安全的方法的使用。

2. 使用过时或遗留的API:严格模式会警告使用过时或遗留的API。

3. 意外的副作用:严格模式可以帮助你发现组件中可能的意外副作用。 防止你写一些有问题的代码

4. 与旧版本React不兼容的代码:严格模式会警告你的代码中可能与未来版本的React不兼容的部分。

Jsx的作用?

可以在js中返回dom,经过babel编译成JS认识的代码。

复制代码
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
  1. 第一个参数: 标签名

  2. 第二个参数:

    1. 子元素

    2. 标签中的一些属性

getDerivedStateFromProps的作用是什么?

它的返回值,会对state进行相同属性覆盖,如果没有和state一样的属性就什么都不做。

执行时机: 挂载和更新都执行,在render之前。

什么场景下可以用这个方法?

  1. 人民币转换大小写

getSnapshotBeforeUpdate的特点

执行时机:只会更新的时候执行,在render之后,浏览器页面更新之前

作用:返回值可以传递给componentDidUpdtate

场景:

长列表,需要不断的往里面塞入内容。

更新之前,记住滚轮的位置,传递给componentDidUpdtate,保持滚轮的位置。

getSnapshotBeforeUpdate更新之前记录滚轮的原始位置,传递给componentDidUpdtate。

componentDidUpdtate就使用原始的位置更新dom,保证滚轮的正确性。

React的更新是同步还是异步?为什么?

更新是异步的。

因为React的更新底层的异步(微任务)队列,会将短时间的JS对组件的修改进行合并,1次渲染完成。

useEffect的执行时机?

看课件

useEffect的返回函数执行时机?

  1. 卸载

  2. 依赖项更新

更新的执行,实际上也是用于卸载操作。

应用场景:

组件: 扣扣 聊天工具

作用: 用于卸载。

跟A聊天,跟A建立连接。

复制代码
  useEffect(() => {
       
    // A
    // 伪代码  
    connect(user)
       
   
    return () => {
      console.log('effect返回的函数执行', count)
    }
  },[user])  // A

离开A的页面,跟B建立连接

复制代码
  useEffect(() => {
       
    // B
    // 伪代码  
    connect(user)
       
   
    return () => {
      // A
      console.log('effect返回的函数执行', count)
      disConnect(user)
    }
  },[user])  // A => B

Hooks的钩子为什么要写在顶层作用域?

因为组件的hooks是用链表这种数据结构来进行连接的,通过next属性保持执行顺序。

如果中间的断开,会导致后面的钩子找不到。

useEffect和useLayoutEffect的区别?

useEffect(异步)是在commit的第一个阶段,js操作dom之前调用,但是在浏览器渲染完成之后调用。

useLayoutEffect(同步),JS操作完dom之后调用,在浏览器渲染之前。

useLayoutEffect的应用场景?

见第十一课的demo

useMemo的应用场景?

它是用于react渲染过程 中的性能优化。

适用于: 父组件要进行更新,子组件的重新render计算量比较大,而且结果可以复用。就可以使用useMemo来提升父组件引起子组件不必要渲染的性能优化。

我该在哪些地方使用useMemo?

useMemo在项目中一定是不得已用才使用(已经出现了明显的问题)。

  1. useMemo本身有性能消耗,缓存消耗内存,useMemo自身状态的维护也是有性能开销的

  2. useMemo会增加开发成本,代码变的很复杂不好维护

  3. react官方在未来会取消useMemo这个钩子

react的渲染规律?

只要父组件进行的setState,父组件本身会重新render,所有子组件也会重新render

useMemo和useCallback的区别?

实际上没有本质区别,只是一个用于缓存函数,一个用于缓存数据。

纯粹为了代码的可维护性。

forwardRef的作用?

实际上函数式组件是没有ref的。

那我们想拿到函数组件内部某个dom实例,就可以通过forwardRef转发出去。

useContext的作用?

主要用于跨组件传值。

核心是父组件使用Provider包裹,给所有子组件注入上下文(值)。

子孙组件就可以通过useContext拿到顶层组件注入的值。

一般修改状态,可以把状态和修改函数一并注入。

React并发更新的作用?

  1. 基于Fiber数据结构,进行细粒度的任务拆分

  2. 在浏览器空闲时间执行,requestIdleCallback 的思想

因为requestIdleCallback这个东西兼容性不好,React目前是使用PostMessage去模拟实现的,它是宏任务的异步。

​​​​​​​

useTransition和useDeferredValue的区别?

解决的问题是一样的。

只是应用场景有点细微的区别。

一般useDeferredValue比较适合用于组件接受的Props参数导致渲染缓慢的优化。

useTransition比较适合在自己组件内部本身来进行优化。

场景:

写了两个组件:

TabContainer也是一个组件,假设是我自己开发的,我提供给别人使用。但是我希望这个组件,别人拿来用的时候已经是性能不错的,就可以使用useTransition。

SlowList是一个组件,假设是别的团队开发的,我是组件使用者。使用者想优化这个组件的渲染,把它变成低优先级就可以使用useDeferredValue。

react的hook一定要写在顶层作用域吗?

不是的,比如说use这个hook就不用,这是一个特殊的存在。

useDebugValue的作用?

可以利用调试工具,做组件级别的debug。全部用console堆在一起,不方便。

记得开启严格模式!!!

useId的应用场景?

场景:多个密码确定框。

为什么不能用随机数?

因为有一种场景,Nodejs端去做React的服务端渲染(SSR 20K以上工程师要会的技术)。

需要确保Node端生成Id和前端(浏览器)一致。

useImperativeHandle的应用场景?

作用: 自定义转发出去的ref

应用场景: 我不希望开发者直接操作dom,你用我给你定义的方法就好。

useInsertionEffect

useInsertionEffect 是为 CSS-in-JS 库的作者特意打造的。

如果你需要使用js插入style标签,请使用useInsertionEffect。

不要用其他,否则可能发生错误。

useSyncExternalStore的作用?

解决状态撕裂问题。

详情见课件

相关推荐
细节控菜鸡3 小时前
【2025最新】ArcGIS for JS点聚合功能实现
开发语言·javascript·arcgis
破浪前行·吴3 小时前
【学习】响应系统
前端·javascript·学习
buibui3 小时前
Vue3组件库搭建5-发布
前端
Sherry0074 小时前
【译】CSS 高度之谜:破解百分比高度的秘密
前端·css·面试
叫我詹躲躲4 小时前
Web Animation性能优化:从EffectTiming到动画合成
前端·javascript
_AaronWong4 小时前
基于 CropperJS 的图片编辑器实现
前端·vue.js·图片资源
叫我詹躲躲4 小时前
3 分钟掌握前端 IndexedDB 高效用法,告别本地存储焦虑
前端·indexeddb
默默地离开4 小时前
React Native 入门实战:样式、状态管理与网络请求全解析 (二)
前端·react native
Q_Q5110082854 小时前
python+springboot+vue的旅游门票信息系统web
前端·spring boot·python·django·flask·node.js·php