React知识点大汇总(全是细节)

React18的介绍

        React是一个用于构建用户界面( user interface )的 JavaScript 库。
        React主要用于构建 UI ,基于 MVC 设计,起源于 Facebook meta ),当年用来架设 Instagram 网站,于 2013年 5 月开源。( MVC1.0 MVVM2.0
        Facebook创造 React 是为了解决一个问题:构建随着时间,数据 不断变化 大规模 应用程序。传统的 节点操作在性能上的瓶颈是很难突破的(DOM 节点的频繁渲染、覆盖更新等),代表为原生 JS 和 JQuery。 React 为了打破当年的节点驱动瓶颈,创造了全新的开发思想:
数据驱动:数据发生改变,视图自动更新,关注点都放在数据上,操作更简单。
最小粒度更新:数据变化后, React 会对比发生变化的节点,仅更新变化的部分。( diff 1.0 / fiber
2.0 最小粒度更新)
组件化开发 React 都是关于构建可复用的组件
组件:具有结构、样式、行为的单一部件

react18新特性

        并发性(Concurrency) :并发性是一种能够同时执行多项任务的能力。在 React 18 中,它是作为主 要新特性出现的。
自动批处理 (Automatic Batching) :为了提高性能,一组 React 将多个状态更新放入一次渲染中的操
作,被称为批处理。
SSR 支持 Suspense
转换 (Transition)
React 的语法偏向于原生 JS

MVC三层架构

M:model:模型,数据在这里面

V:View:视图,页面结构

C:Controllor:控制器,逻辑代码

页面可拆分成三部分:M层,V层,C层
M层:管理数据
V层:渲染页面,也会调用C层,数据来源于M层
C层:通过C层将数据渲染上去, 修改M层数据

React创建项目

全局安装脚手架

yarn global add create-react-app || pnpm i -g create-react-app

以上两个命令都可以

使用脚手架创建项目

create-react-app react-demo # 项目名建议小写英文,多个单词中划线

启动项目

我们可以通过以下命令进行运行项目

cd react-demo # 进入项目
yarn start # 启动

创建一个组件

在创建组件之前先删除src中的文件,这些文件时初始的文件。

添加 src/App.js 组件文件

React 中的组件名用大驼峰
import React from 'react'
export default function App() {
return (
<div>App</div>
)
}

添加 src/index.js 入口文件

在入口文件中指定 DOM 容器,渲染引入的组件
// 入口JS文件
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);

JSX语法(重点)

基本概念

jsx:js的拓展语法,可以在jsx中写html,它相当于一个模板,js的语法糖

JSX 语法的本质:并不是直接把 JSX 渲染到页面上,而是内部先转换成了 createElement 形式,再渲染的。

JSX 的优点

JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化;
它是类型安全的,在编译过程中就能发现错误;
使用 JSX 编写模板更加简单快速。

JSX语法基础

JSX 注释:推荐使用 {/* 这是注释 */}
JSX 中添加 class 类名:需要使用 className 来替代 class htmlFor 替代 label for 属性;
JSX 创建 DOM 的时候,所有节点必须有唯一的根元素进行包裹;
JSX 语法中,标签必须成对出现,如果是单标签,则必须自闭合;
JSX 语法中,渲染动态数据的地方使用一对 { 表达式 } 进行渲染
注意:表达式包含变量、数学运算、有返回值的函数、三元表达式等。表达式的定义是能够返回一个结 果的代码块

JSX的应用

可以嵌套哪些内容呢? —— 基本数据类型、数组、 JSX 元素、函数调用。被嵌套的变量必须用 {} 包起来。这种{} 语法是 JSX 的语法特色。在 JSX 中凡是被 {} 所包裹的东西,我们称之为表达式。
如果嵌套的变量是字符串、数值类型, JSX 会把它们当作文本进行渲染。( v-text
如果嵌套的变量是 undefined null 、布尔值, JSX 会忽略掉它们。
如果嵌套的变量是数组, JSX 会把它们当作列表进行渲染(要加 key )。( v-for
如果嵌套的表达式是函数调用,这个函数的返回值必须是 JSX 支持的变量类型。
如果嵌套的变量是对象,在动态 style 等特殊语法环境下,是支持的。
JSX 元素的属性是动态变量时,也要用 {} 包起来。( v-bind
注意
JSX {} 中只能放置变量和表达式。 {} 中可以发生任何 运算 ,但 运算 的结果必须返回的是
ReactNode 。不能返回 void Symbol BigInt Map Set 等其它数据类型。它默认具有防注入攻
击( XSS
建议不要在 JSX {} JS 语句。
JSX 中添加注释,示例: {/* something */}
React 组件名的首字母必须大写。
const msg = '一闪一闪亮晶晶!'


const count = 10
// const msg = '你好,世界'
const flag = true
const list = ['html', 'css', 'javascript','react']
const cls = 'demo'
// const str = <h2>我是一个h2标签</h2>
const styleobj = {
    color: 'green',
    backgroundColor: 'skyblue',
    fontSize:'36px'
}
const title = '这个是一个介绍jsx语法的标题'
const str = '<h1>你好</h1>'
// jsx语法:在需要使用到动态数据的地方,替换成一对花括号即可,在花括号内加上变量名,即可渲染动态数据
// {表达式}:能够返回一个结果的代码块(变量,数学运算,三元表达式,(有return)的函数,正则表达式,)
// 常用的函数(表达式):map,every,some,include等

export default function First() {
    return (
        <div>
            <h1 title={title}>一闪一闪亮晶晶</h1>
            <h2>{msg}</h2>
            <div>jsx渲染数字:{ count }</div>
            <div style={styleobj}>jsx渲染字符串:{ msg }</div>
            <div>jsx渲染布尔值:{ flag }</div>{/*undefined、null、布尔值会自动忽略*/}
            <div>jsx三元表达式:{ flag ? '我是真的' : '我是假的' }</div>
            <div style={ { color: 'red' } } id={ cls }>jsx渲染标签属性和样式</div>
            <div>jsx渲染标签对象:{ str }</div>
            <p>数学运算:{10 * 10}</p>
            <div>jsx渲染数组:{list.map(v => <span key={v}>{v} </span>)}</div>{/*如果嵌套的变量是数组,JSX会把它们当作列表进行渲染(要加key)*/}
            <div>
                我喜欢的技术有下面几种:
                {
                    // 在jsx中循环渲染的每个子元素一定要拥有一个唯一的key属性,该属性只能是数字或字符串,不建议使用索引
                    list.map(item => {
                        return <h2 key={ item}>{ item }</h2>
                    })
                }
            </div>
            <p style={{ color: 'green', backgroundColor: 'red' }}>满天都是小眼睛</p>
            {/* 相当于innerHTML */}
            <p>{str}</p>
            <p dangerouslySetInnerHTML={{ __html:str }}></p>
        </div>
    )
}

JSX语法中有三个不一样的属性

className (相当于 html class 属性)
htmlFor (相当于 html 中的 for 属性)
tabIndex (相当于 html 中的 tabindex 属性)

JSX语法中新增了三个属性

key 渲染一个列表时,或者渲染一个数组时,都要加 key ,为了让 “diff 运算 更加高效。
ref 用于快速地访问 DOM 对象或者访问 JSX 实例对象。
dangerouslySetInnerHTML JSX 节点中插入一段可以参与渲染的 HTML 字符串(相当于 Vue 中的 v
html
JSX 的注意点
JSX 元素必须要用一个  元素或者空元素 包裹起来
return (
    <div>
      <h1>点击的次数:{count}</h1>
      {/* 在这里将B和C引入 */}
      {/* 给B一个单击事件的函数 */}
      <B fn={aaa} />
      <C />
    </div>
  );

JSX是不可变对象

1. 什么是不可变对象

对象不变性在任何编程语言中都是一个重要的概念。它会限制对象修改并防止不需要的更改。简而言之,对象的不变性就是将它的状态变为只读的

为什么不可变性在React中非常重要?

不可变性指的是不直接修改数据,而是使用新的数据替换旧的数据。
不可变性带来的优势:
1. 撤销和回退操作在开发中是很常见的,不直接在数据上进行修改,可以帮助我们更好的回溯数据。
2. 更容易跟踪数据的改变。
3. 方便确定 React 重新渲染的时机。

事件处理

添加事件

React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:
React 事件的命名采用小驼峰式( camelCase ),而不是纯小写。
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串
import React from 'react'
export default function Event() {
const handleClick = () => {
console.log('我被执行了')
}
return (
<div>
<button onClick={ handleClick }>按钮</button>
</div>
)
}

event对象

在这里, e 是一个合成事件。 React 根据 W3C 规范 来定义这些合成事件,所以你不需要担心跨浏览器的兼容性问题。React 事件与原生事件不完全相同。
import React from 'react'
export default function Event() {
const handleClick = e => {
console.log(e, '我被执行了')
}
return (
<div>
<button onClick={handleClick}>按钮</button>
/*
如果需要给事件处理函数额外传入一个数据,可以在外面包一个箭头函数
<button onClick={(e) => handleClick(e, msg)}>按钮</button>
*/
</div>
)
}

React的状态定义及修改

useState 是一个 Hook 函数,让你在函数组件中拥有 state 变量。它接收一个初始化的 state ,返回是一 个数组,数组里有两个元素,第一个元素是当前状态值和另一个更新该值的方法。
这儿有一些需要记住的关键的点:
        修改方法不会立即更新值
        如果你需要用到之前的值更新状态,你必须将之前的值传递给该方法,则它会返回一个更新后的
值, eg: setMessage(previousVal => previousVal + currentVal)
        如果你使用同样的值作为当前状态,则React 不会触发重新渲染。( React 是用 Object.is 来做比较的)
        useState 不像类组件中的 this.setState 合并对象,它是直接替换对象。
        useState 和所有的 hooks 遵循相同的规则,特别是,注意这些函数的调用顺序。

正确的使用方式

import React, { useState } from 'react'
export default function StateCom() {
const [ msg, setMsg ] = useState('你好,世界')
const handleClick = () => {
setMsg('你好,李焕英')
}
return (
<div>
<h1>{ msg }</h1>
<button onClick={handleClick}>按钮</button>
</div>
)
}
// 循环渲染
import React, { useState } from 'react'
export default function Loop() {
const [list, setList] = useState(['html', 'css', 'javascript', 'vue'])
console.log(list)
return (
<>
<span>我擅长:</span>
{
list.map(v => <p key={ v }> { v }</p>)
}
</>
)
}

react hooks

useEffect

Effect Hook 可以让你在函数组件中执行副作用操作
        数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用。 不管你知不知道这些操作,或 是“ 副作用 这个名字,应该都在组件中使用过它们。也可以模仿生命周期。
        通过使用这个 Hook ,你可以告诉 React 组件需要在渲染后执行某些操作。 React 会保存你传递的函数 (我们将它称之为 “effect” ),并且在执行 DOM 更新之后调用它。在这个 effect 中,我们设置了 document 的 title 属性,不过我们也可以执行数据获取或调用其他命令式的 API
import React from "react";
import { useState } from "react";
import { useEffect } from "react";
export default function UseEffect() {
  const [msg, setMsg] = useState("你好世界");
  // 生命周期:componentDidMount 挂载后    componentDidUpdate 更新后      componentWillUnmount 卸载前
  // useEffect(callback,[依赖项])
  useEffect(() => {
    const timer = setInterval(() => console.log("定时器执行"), 1000);
    console.log("使用useEffect模拟componentDidMount生命周期");
    // alert("Component has been mounted!");
    return () => {
      // 清除定时器
      clearInterval(timer);
      console.log("使用使用useEffect模拟componentWillUnmount生命周期");
    };
  });
  useEffect(() => {
    //   给useeffect传入第二个参数,第二个参数是一个数组,数组里是要监听的数据变量名
    console.log("使用useEffect模拟componentDidUpdate生命周期");
  }, [msg]);
  return (
    <div>
      <h1>{msg}</h1>
      <button onClick={() => setMsg("你好李焕英")}>改名</button>
    </div>
  );
}
// useEffect:执行副作用操作
//            处理清理逻辑: 通过返回一个函数,可以在组件销毁时执行一些清理逻辑,例如清除定时器、取消订阅等。
//            模拟生命周期
// useEffect有两个参数,一个是回调,一个是数组

useRef

        ref 是一种访问 DOM 的主要方式。如果你将 ref 对象以 <div ref={myRef} /> 形式传入组件,则无论该节点如何改变,React 都会将 ref 对象的 .current 属性设置为相应的 DOM 节点。然而, useRef() 比 ref 属性更有用。它可以很方便地保存任何 可变值 。这是因为它创建的是一个普通 Javascript 对象。而 useRef() 和自建一个 {current: …} 对象的唯一区别是, useRef 会在每次渲染时返回 同一个 ref 对象
useRef如何使用
import React, { useRef, useEffect } from 'react'
function ReactCustomComponent() {
const inputEl = useRef(null);
// `current` 指向已挂载到 DOM 上的文本输入元素
useEffect(() => inputEl.current.focus())
return (
<>
<input ref={inputEl} type="text" />
</>
);
}

memouseMemouseCallback

        一句话概括 memo useMemo useCallBack 主要用于避免 React Hooks 中的重复渲染,作为性 能优化的一种手段,三者需要组合并结合场景使用。
import React, { useState, useMemo, useCallback } from "react";
import B from "./B";
import C from "./C";
export default function A() {
  // 声明数量状态
  const [count, setCount] = useState(0);
  // 修改数量的方法
  //   const handleClick = () => setCount((pre) => pre + 1);
  //   useMemo  缓存方法
  //   const aaa = useMemo(() => {
  //     return handleClick;
  //   }, []);
  //   const aaa = useMemo(() => () => setCount((pre) => pre + 1), []); //简写/高级方式
  //   useCallback  缓存方法
  const aaa = useCallback(() => setCount((pre) => pre + 1), [count]);
  const bbb = useCallback(() => setCount((pre) => pre - 1), [count]);
  //   const handleClick2 = () => setCount((pre) => pre--);
  console.log("A组件更新了");
  return (
    <div>
      <h1>我被点击了{count}次</h1>
      <B fn={aaa} />
      <C fn={bbb} />
    </div>
  );
}
import React from "react";
import { memo } from "react";
export default memo(function B(props) {
  //   console.log(props);
  console.log("B组件更新了");
  return <div onClick={props.fn}>B</div>;
});

// props 属性  父传子
import React, { memo } from "react";

export default memo(function C(props) {
  console.log("C组件更新了");
  return <div onClick={props.fn}>C</div>;
});

// memo 避免React Hooks中的重复渲染  缓存组件
注意:不要滥用 useMemo useCallBack
        使用useMemo useCallBack 时,本身会产生额外的开销, 并且这两个方法必须和 memo 搭配使用,否 则很可能会变成负优化
        因此,在实际项目中,需要结合实际场景,评估重复渲染和创建useCallBack/useMemo 的开销来判断到 底用不用useCallBack useMemo

自定义hook

自定义 Hook 是一个函数,其名称以 use 开头,函数内部可以调用其他 Hook
在自定义 Hook 顶层 可以 无条件地 调用其他 Hook( useState , useEffect )
我们可以自由决定自定义 Hook 参数 返回值
自定义 Hook 必须 use 开头 ,这样方便判断该函数内部是否调用了内部 Hook
React 能自动检查 Hook 是否违反了 Hook 的规则 ( Hook 规则部分 )
每次使用自定义 Hook 时,其中的 state 和副作用都是完全隔离的。
Hooks 和普通函数在语义上是有区别的,就在于函数中有没有用到其它 Hooks
就是说如果你创建了一个 useXXX 的函数,但是内部并没有用任何其它 Hooks ,那么这个函数就不
是一个 Hook ,而只是一个普通的函数。但是如果用了其它 Hooks ,那么它就是一个 Hook

自定义hooks

import { useEffect, useState } from 'react'
export const useResize = () => {
let [ width, setWidth ] = useState(document.body.clientWidth - 30)
const resizeFn = () => {
setWidth(document.body.clientWidth - 30)
}
useEffect(() => {
window.addEventListener('resize', resizeFn)
return () => {
window.removeEventListener('resize', resizeFn)
}
}, [])
return {
width,
setWidth
}
}

使用自定义Hook

import React from 'react'
import { useResize } from './useResize'
export default function Table() {
const { width, setWidth } = useResize()
return (
<div style={ { width, height: 200, backgroundColor: 'green' } }>我假装是一个
表格table</div>
)
}

Hook 规则

只在最顶层使用 Hook
不要在循环、条件或嵌套中调用 Hook
只在 React 函数中调用 Hook
react 的函数组件中调用 Hook
在自定义 Hook 中调用其他 Hook
要确保 Hook 的调用顺序在每次渲染中都是相同的

ahook的使用

        ahooks是由蚂蚁 umi 团队、淘系 ice 团队以及阿里体育团队共同建设的 React Hooks 工具库。 ahooks 基于 React Hooks 的逻辑封装能力,提供了大量常见好用的 Hooks ,可以极大降低代码复杂度,提升开 发效率。

安装

$ npm install --save ahooks
# or
$ yarn add ahooks
使用
import { useRequest } from 'ahooks' ;

实用hooks

全新的 useRequest 异步管理
import React from 'react'
import axios from 'axios'
import { useRequest } from 'ahooks'
export default function Hooks() {
const getData = async () => {
return await axios.get('https://api.uomg.com/api/rand.qinghua', {
format: 'json' })
}
const { data, loading, error } = useRequest(getData, {
pollingInterval: 2000, // 轮询
loadingDelay: 300 // loading状态延时
// 其它配置项请参照官方文档
})
return (
<div>
{ loading && '正在加载中' }
{ error && '报错了' }
{ data && data.data.content }
</div>
)
}

hooks闭包陷阱

什么是闭包陷阱

        闭包是指跨作用域访问变量。在 React 中, Hooks 函数也是闭包。 React Hooks 的闭包陷阱与普通
JavaScript 中的闭包陷阱类似,但是由于 React Hooks 的设计,使用 Hooks 时可能会遇到一些特定的问 题。
React Hooks 中的闭包陷阱主要会发生以下几种情况:
useState 中的闭包陷阱
useEffect 中的闭包陷阱
useCallback 中的闭包陷阱

useState 陷阱

陷阱:【异步陷阱】

useEffect 陷阱

陷阱:【过期闭包】

useCallback 陷阱

陷阱:【获取父组件的值,不是最新】
  • 38
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是React中常用的一些知识点: 1. 组件:React将用户界面拆分为可重用的组件,组件是构建React应用的基本单元。组件可以是函数组件或者类组件。 2. JSX:JSX是一种类似于HTML的语法扩展,可以在JavaScript代码中编写类似HTML的结构。它允许我们以声明式方式描述UI组件的结构。 3. Props:Props是组件的属性,用于传递数据和配置参数给组件。通过props,我们可以向子组件传递数据并进行组件之间的通信。 4. State:State是用于存储和管理组件内部的数据的对象。当state发生变化时,React会自动重新渲染组件,并更新相应的视图。 5. 生命周期:React组件具有生命周期方法,这些方法在组件的不同阶段被调用,例如组件被创建、更新、卸载等。 6. Hooks:Hooks是React 16.8版本引入的特性,它允许我们在无需编写类组件的情况下使用状态和其他React特性。常用的Hooks包括useState、useEffect、useContext等。 7. 条件渲染:React允许我们根据条件来渲染不同的内容或组件。常用的条件渲染方式包括if语句、三元表达式和逻辑与(&&)运算符等。 8. 列表渲染:React提供了map方法来遍历数组或者列表,动态生成列表项。通过列表渲染,我们可以根据数据动态生成多个相似的组件。 9. 表单处理:React提供了一些事件和处理函数来方便地处理表单的输入和提交。通过onChange事件,我们可以监听表单元素的值变化,并将其保存到组件的state中。 10. 组件通信:React中的组件通信可以通过props、状态提升、上下文(Context)和全局状态管理工具(如Redux)等方式来实现。 这些是React中常用的知识点,当然还有更多深入的内容和特性可以学习和掌握。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值