React 基础学习02

以下是React18版本的基础学习资源
点击我获取更多学习资源

1. …模板扩展符

import logo from './logo.svg';
import './App.css';
function App() {const imgData = {className: 'small',style: {wdith: '200px',height: '200px',backgroundColor: 'grey'}}return (<div className="App"><img src={logo}alt=""{...imgData}/></div>);
}export default App;

2. 模板扩展发嵌套使用

import './App.css';function Detail({content, active}) {return (<><p>{content}</p><p>状态:{active}</p></>)
}
function Article({title, detailData}) {return (<div><h2>{title}</h2><Detail {...detailData}></Detail></div>)
}
function App() {const articleData = {title: '标题111',detailData: {content: '内容111',active: true}}return (<><Article{...articleData}/></>);
}export default App;

3. 默认插槽

import './App.css';function List({children}) {return (<ul>{children}</ul>)
}
function App() {return (<><List><li>列表1</li><li>列表2</li></List></>);
}export default App;

4. 带名字插槽

import './App.css';function List({children, title, footer = <div>默认底部</div>}) {return (<><h2>{title}</h2><ul>{children}</ul>{footer}</>)
}
function App() {return (<><Listtitle="列表title"footer={<p>这是底部内容</p>}><li>列表1</li><li>列表2</li></List></>);
}export default App;

5. 子调用父

import './App.css';
import {useState} from 'react'
function Detail({onActive}) {const [status, setStatus] = useState(false) function handleClick() {setStatus(!status)onActive(status)}return (<div><button onClick={handleClick}>按钮</button><p style={{display: status ? 'block' : 'none'}}>Detail内容</p></div>)
}
function App() {function handleActive (status) {console.log(status)}return (<><Detail onActive={handleActive}></Detail></>);
}export default App;

6. useReducer作用

import './App.css';
import {useReducer, useState} from 'react'function countReducer(state, action) {switch(action.type) {case 'increment':return state + 1case 'decrement':return state - 1default:throw new Error()}
}
function App() {
const [state, dispatch] = useReducer(countReducer, 0)
const handleIncrement = () => dispatch({type: 'increment'})
const handleDecrement = () => dispatch({type: 'decrement'})return (<><button onClick={handleIncrement}>+</button><span>{state}</span><button onClick={handleDecrement}>-</button></>);
}export default App;

7. 父调用子 forwardRef, useImperativeHandle, useRef

import './App.css';
import { forwardRef, useImperativeHandle, useRef } from 'react'const Child = forwardRef(function(props, ref) {useImperativeHandle(ref, () => ({myFun: ()=> {console.log('子方法被调用')}}))return (<div>子组件</div>)
})
function App() {const childRef = useRef()const handleClick = () => {childRef.current.myFun()}return (<><Child ref={childRef} /><button onClick={handleClick}>调用子方法</button></>);
}export default App;

8. useEffect 作用

import './App.css';
import { useEffect, useState } from 'react'function App() {const [count, setCount] = useState(0)const [count2, setCount2] = useState(0)// 只要界面一变化,都会触发useEffect(() => {console.log('useEffect')return () => {// 当页面卸载执行,清理数据}})// useEffcet(() => {// return () => {//   console.log('类似于componentWillUnmount,通常用于清除副作用');// }// }, [])//  useEffcet(() => {
// 	console.log('类似于componentDidMount,通常在此处调用api获取数据')
//   }, [])//  useEffect useEffect 返回的是一个清理函数,//不能是async的promise,如果里面有异步执行,可以用以下方法// useEffect(() => {//   console.log('useEffect')//   return () => {//     ;(async () => {//       const data = await http.get('....')//     })();//     // 当页面卸载执行,清理数据//   }// })//只有count才会触发// useEffect(() => {//   console.log('useEffect')// }, [count])const handleClick = () => {setCount(count + 1)}const handleClick2 = () => {setCount2(count2 + 1)}return (<><button onClick={handleClick}>点击触发{count}</button><button onClick={handleClick2}>点击触发2{count2}</button></>);
}export default App;

9. useMemo缓存数据,避免重复计算

import './App.css';
import { useMemo, useState } from 'react'function DoSomeMath ({value}) {// 利用useMemo,可以缓存result,不会重新计算,但该函数依然会执行console.log('DosomeMathc执行了')const result = useMemo(() => {console.log('DosomeMathc2执行了')let result = 0for (let i = 0; i < 100000; i++) {result += value * 2}return result}, [value])return (<div>{result}</div>)
}function DoSomeMath2 ({value}) {// 外面变化,在value没变化的情况下,内部依然都要重新计算,不符合逻辑console.log('DosomeMathc执行了')let result = 0for (let i = 0; i < 100000; i++) {result += value * 2}return (<div>{result}</div>)
}
function App() {const [inputValue, setInputValue] = useState(5)const [count, setCount] = useState(0)return (<><p>count值为: {count}</p><buttononClick={() => setCount(count + 1)}>点击更新</button><br/><input type="number"value={inputValue}onChange={(e) => setInputValue(parseInt(e.target.value))} /><DoSomeMath value={inputValue} /></>);
}export default App;

10. memo 记忆组件和useCallback记忆函数

import './App.css';
import { memo, useCallback, useState } from 'react'function MyButton2 ({onClick}) {// 外部变化,每部都会被渲染一次console.log('mybutton被执行')return <button onClick={onClick}>子组件</button>
}const MyButton = memo(function ({onClick}) {// 外部变化,每部都会被渲染一次console.log('mybutton被执行')return <button onClick={onClick}>子组件</button>
})
function App() {const [count, setCount] = useState(0)const handleUpdate = () => setCount(count + 1)// app 每次重新渲染,handleClick都是一个新的函数,依然会触发子组件更新const handleClick2 = () => {console.log('handleClick被点击...')}
// 利用useCallback可以缓存住handleClick函数,成为记住组件const handleClick = useCallback( () => {console.log('handleClick被点击...')}, [])return (<><p>Count: {count}</p><button onClick={handleUpdate}>点击</button><br/><MyButton onClick={handleClick}></MyButton></>);
}export default App;

11. mobx

[https://blog.csdn.net/qq_53123067/article/details/129707090]

import { makeAutoObservable, autorun, reaction, runInAction } from "mobx";class Counter {constructor(){//makeAutoObservable的使用:makeAutoObservable就像加强版的makeObservable,默认情况下它将推断所有的属性,推断的规则为:所有的属性都成为observable,所有的方法都成为action,所有的计算属性都成为computed (计算属性接下来会讲到)。具体的使用如下:// 参数1:target让对象变成可观察// 参数2:排除属性和方法// 参数3:指定自动绑定thismakeAutoObservable(this, {}, {autoBind: true})}count = 1;increment(){this.count++}incrementAsync(){setTimeout(() => {runInAction(() => {this.count++})}, 1000);}decrement(){this.count--}reset(){this.count = 0}// 计算属性get doubleCount() {return this.count * 2}getDoubleCount() {return this.count * 2}
}const counter = new Counter()
// 监听counter变化, 初始化会执行一次
autorun(() => {console.log('监听count:', counter.count)},)// 监听数据的变化
//reaction类似于autorun,但可以更加精细地控制要跟踪的可观察对象,与autorun不同,reaction在初始化时不会自动运行。
// reaction接收两个参数,参数1:data函数,其返回值会作为第二个函数的输入;参数2:回调函数reaction(() => counter.count, (value, oldValue) => {console.log('count发生变化', value, oldValue)})
export default counter

app.js

import './App.css';
import { memo, useCallback, useState } from 'react'
import { observer } from 'mobx-react-lite'
import counter from './store/counter';
// import counter2 from './store/counter';function App() {return (<><h2>计数器案例</h2><div>点击次数:{counter.count}</div>{/* <div>点击次数:{counter2.count}</div> */}<div>计算属性次数:{counter.doubleCount}</div><button onClick={()=>counter.increment()}>1</button><button onClick={()=>counter.decrement()}>1</button><button onClick={()=>counter.incrementAsync()}>异步加1</button><button onClick={()=>counter.reset()}>重置</button></>);
}export default observer(App);

12. useEffect 第二个参数详解

  1. undefined: 任何状态改变都会执行
  2. 不是数组:报警
  3. 是空数组: 回调只会再函数组件调用执行一次(类似mounted)
  4. 是有元素的数组:元素为状态的话,状态更新,回调测重新执行一次

13. createContext作用

import './App.css';
import React, {useContext } from 'react'function App() {const AppContext = React.createContext()const A = () => {const {name} = useContext(AppContext)return (<p>A组件{name}嵌入了B<B/></p>)}const B = () => {const {name} = useContext(AppContext)return (<p>B组件{name}</p>)}return (<AppContext.Provider value={{name: 'context值'}}><A></A></AppContext.Provider>);
}export default App;

14. LayoutEffect Hook

useLayoutEffect() :和useEffect相同,都是用来执行副作用,但是它会在所有的DOM变更之后同步调用effect。useLayoutEffect和useEffect最大的区别就是一个是同步,一个是异步。从这个Hook的名字上也可以看出,它主要用来读取DOM布局并触发同步渲染,在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。官网建议还是尽可能的是使用标准的useEffec以避免阻塞视觉更新

15. 自定义组件

import { useState,useEffect } from "react";
const usePerson = ({name}) => {const [loading, setLoading] = useState(true)const [person, setPerson] = useState({})useEffect(() => {setLoading(true)setTimeout(()=> {setLoading(false)setPerson({name})},2000)},[name])return [loading,person]
}
const AsyncPage = (name)=> {const [loading,person] = usePerson(name)return (<>{loading?<p>Loading...</p>:<p>{ person.name }</p>}</>)
}const App = ()=> {const [state,setState] = useState('')const changeName = (name)=> {setState(name)}return (<><AsyncPage name={ state } /><button onClick={ ()=> { changeName('郭靖')}}>郭靖</button><button onClick={ ()=> { changeName('黄蓉')}}>黄蓉</button></>)
}export default App;
//上面代码中,封装成了自己的Hooks,便于共享。其中,usePerson()为自定义Hooks它接受一个字符串,返回一个数组,数组中包括两个数据的状态,之后在使用usePerson()时,会根据传入的参数不同而返回不同的状态,然后很简便的应用于我们的页面中。//这是一种非常简单的自定义Hook。如果项目大的话使用自定义Hook会抽离可以抽离公共代码,极大的减少我们的代码量,提高开发效率。

16. 路由传参三种方式

react router v6 获取传参需要用两个 hook,分别是 useParams(params)和 useSearchParams(search)(1)useParamsparams 传参import { NavLink } from 'react-router-dom';{/* 路由定义 /article/:id */}
<NavLink to={`/article/1`}>文章1</NavLink>
接收参数import { useParams } from 'react-router-dom'/* params */
const params = useParams();
const { id } = params;2)useSearchParamssearch 传参import { NavLink } from 'react-router-dom';<NavLink to={`/article?id=1`}>文章1</NavLink>
接收参数import { useSearchParams } from 'react-router-dom'/* search */
let [searchParams, setSearchParams] = useSearchParams();
const { id } = searchParams;3)useLocationstate 传参import { NavLink } from 'react-router-dom';<NavLink to="/article" state={{ id: 1 }}>文章1</NavLink>
接收参数import { useLocation } from 'react-router-dom'let location = useLocation();
const { id } = location.state;

17. 路由跳转

参考 [https://zhuanlan.zhihu.com/p/518339176]

useHistory 已废弃,而是使用 useNavigateimport { FC, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Button } from 'antd';interface IndexProps{}const Index: FC<IndexProps> = () => {const navigate = useNavigate();// 返回const handleBack = () => navigate(-1);// 前进const handleForward = () => navigate(1);// 刷新const handleRefresh = () => navigate(0);//return <><Button type="primary" onClick={handleBack}>返回</Button><Button type="primary" onClick={handleForward}>前进</Button><Button type="primary" onClick={handleRefresh}>刷新</Button>{/* 跳转路由 */}<Button type="primary" onClick={() => navigate('/article/1', { replace: true })}>params</Button><Button type="primary" onClick={() => navigate('/article?id=1', { replace: true })}>search</Button><Button type="primary" onClick={() => navigate('/article', { replace: true, state: { id: 1 } })}>state</Button></>
}export default Index;

18. 配置路径别名

//vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import path from 'path';
import {join} from 'node:path'
// https://vitejs.dev/config/
export default defineConfig({plugins: [react()],resolve: {alias: {'@': path.resolve(__dirname, './src/')// '@': join(__dirname, './src/')}}
})//tsconfig.json{"compilerOptions": {"baseUrl": ".","paths": {"@/*": ["./src/*"]},"target": "ES2020",......}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/656009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaWeb中的Filter(过滤器)和 Listener(监听器)

提示&#xff1a;这两个东西听起来似乎很难&#xff0c;实际上是非常简单的&#xff0c;按照要求写就行了&#xff0c;一定不要被新名词给吓到了。 JavaWeb中的Filter&#xff08;过滤器&#xff09; 一、Filter&#xff08;过滤器&#xff09;1.如何编写 Filter2.Filter 中的细…

最小二乘圆柱拟合(高斯牛顿法)

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 本期话题&#xff1a;最小二乘圆柱拟合 相关背景资料 点击前往 圆柱拟合输入和输出要求 输入 8到50个点&#xff0c;全部采样自圆柱上。每个点3个坐标&#xff0c;坐…

自动化测试的10大误区!

自动化测试因提高效率&#xff0c;减少重复工作的特性而被广泛采用。然而&#xff0c;随着自动化测试的普及&#xff0c;自动化测试也面临一系列挑战和误解。 这些误区不仅影响了测试的有效性&#xff0c;还会导致一定的项目风险&#xff0c;为了确保自动化测试能够真正提升测…

【EI会议征稿通知】2024年第四届激光,光学和光电子技术国际学术会议(LOPET 2024)

2024年第四届激光&#xff0c;光学和光电子技术国际学术会议(LOPET 2024) 2024 4th International Conference on Laser, Optics and Optoelectronic Technology 2024年第四届激光&#xff0c;光学和光电子技术国际学术会议(LOPET 2024)将于2024年5月17日-19日在中国重庆举行。…

长度最小的子数组[中等]

一、题目 给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的连续子数组[numsl, numsl1, ..., numsr-1, numsr]&#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回0。 示例 1&#xff1a; 输入&#xff…

【iOS ARKit】光照效果--光源

光照 在现实世界中&#xff0c;光扮演了极其重要的角色&#xff0c;没有光万物将失去色彩&#xff0c;没有光世界将一片漆黑。在3D数字世界中亦是如此&#xff0c;3D数字世界本质上是一个使用数学精确描述的真实世界复本&#xff0c;光照计算是影响这个数字世界可信度的极其重要…

迷你型洗衣机好用吗?迷你内裤洗衣机排名前十名推荐

随着大家工作的压力越来越大&#xff0c;下了班之后只能想躺平&#xff0c;在洗完澡之后看着还需要手洗的内衣裤真的很头疼。有些小伙伴还有会攒几天再丢进去洗衣机里面一起&#xff0c;而且这样子是非常不好的&#xff0c;用过的内衣裤长时间不清洗容易滋生细菌&#xff0c;而…

Redis学习——高级篇④

Redis学习——高级篇④ Redis7高级之Redis与Mysql数据双写一致性工程案例&#xff08;四&#xff09; 4.1 MySQL主从复制原理4.2 canal 工作原理4.3 mySQL->canal->redis 双写一致性1.环境2.配置Mysql3.配置canal4. Canal客户端&#xff08;Java编写&#xff0…

【力扣经典面试题】27. 移除元素

题目描述&#xff1a; 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑…

JavaScript-for循环的执行顺序

1.目标 掌握for执行顺序 2.实现思路 使用for循环输出0-到5 3.代码实现 Document 4.总结 for执行顺序 1.执行 var i 0 变量初始化 条件判断 是否成立 成立 执行循环体 不成立 退出for循环

TypeScript(五) 条件语句

1. 条件语句 1.1. 描述 条件语句用于基于不同的条件来执行不同的动作。   条件语句是通过一条或多条语句的执行结果&#xff08;true或false&#xff09;来决定后面执行的代码块。 1.2. 常使用的条件语句 &#xff08;1&#xff09;if语句 - 只有当指定条件为true时&#…

STL_list

一、有关list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。Ii…

Docker容器引擎(6)

目录 一.什么是consul 解决什么问题&#xff1f; consul的模式&#xff1a; 二.consul 部署 consul服务器&#xff1a; 查看版本&#xff1a; 设置代理&#xff0c;在后台启动 consul 服务端&#xff1a; 进行后台启动&#xff1a; 查看集群信息&#xff1a; 访问页面…

云计算底层技术奥秘、磁盘技术揭秘、虚拟化管理、公有云概述

云计算基础 实验图例 虚拟化平台安装 创建虚拟机 1、创建虚拟机 2cpu&#xff0c;4G内存&#xff08;默认用户名: root 密码: a&#xff09; 2、验证 ecs 是否支持虚拟化 [rootecs ~]# grep -Po "vmx|svm" /proc/cpuinfovmx... ...[rootecs ~]# lsmod |grep kvm…

Linux 网络分析 Wireshark

这篇记录一些 Wireshark 的使用操作&#xff0c;有兴趣的建议看看 《Wireshark网络分析就这么简单》 写的很好&#xff0c;有趣能看进去。 Wireshare 是一个常用的并且很强大网络包分析软件&#xff0c;可以抓包也可以导入tcpdump的导出数据分析。pcap 这个后缀的文件可以用 wi…

【算法专题】前缀和(附图解、代码)

&#x1f4d1;前言 本文主要是前缀和的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#xff1a;努力一点&…

Orion-14B-Chat-Plugin本地部署的解决方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

WebSocket 整合 记录用法

WebSocket 介绍 WebSocket 是基于tcp的一种新的网络协议,可以让浏览器 和 服务器进行通信,然后区别于http需要三次握手,websocket只用一次握手,就可以创建持久性的连接,并进行双向数据传输 Http和WebSocket的区别 Http是短连接,WebSocket’是长连接Http通信是单向的,基于请求…

互联网加竞赛 基于深度学习的人脸表情识别

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的人脸表情识别 该项目较…

HiveSQL题——排序函数(row_number/rank/dense_rank)

一、窗口函数的知识点 1.1 窗户函数的定义 窗口函数可以拆分为【窗口函数】。窗口函数官网指路&#xff1a; LanguageManual WindowingAndAnalytics - Apache Hive - Apache Software Foundationhttps://cwiki.apache.org/confluence/display/Hive/LanguageManual%20Windowin…