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的作用?

解决状态撕裂问题。

详情见课件

相关推荐
恋猫de小郭4 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅11 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606112 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了12 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅12 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅12 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅13 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment13 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅13 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊13 小时前
jwt介绍
前端