react创建项目常见的三大Hook

news/2024/10/2 10:31:08

react创建项目&&常见的三大Hook

创建react脚手架项目

全局安装 create-react-app 工具:

npm i -g create-react-app

查看安装工具的版本号,注意V大写

create-react-app -V

进入要创建的文件目录创建react项目,名为:react_project

create-react-app react_project

启动项目会默认3000端口号打开浏览器

npm start

目录结构

node_modules/: 存放项目依赖包的目录。该目录会在运行 npm install 后生成public/: 存放公共静态资源文件的目录favicon.ico: 浏览器标签上的图标。index.html: 主页面。logo192.pnglog512.png:logo图manifest.json: 应用加壳的配置文件,定义了应用的图标、启动配置、显示模式等。robots.txt:爬虫协议文件,控制哪些内容可以被抓取和索引,优化搜索引擎的表现,减少服务器负担,并保护网站的敏感数据。src/:源码文件夹App.css: App 组件的样式文件。App.js: 主组件文件,包含应用的主要内容。App.test.js: 对 App 组件的测试文件。index.css: 全局样式文件。index.js: 应用的入口文件,将 App 组件渲染到 HTML 文件中。logo.svg: 默认的 React Logo 图像文件。reportWebVitals.js: 用于记录和报告 Web Vitals 性能指标的文件。.gitignore: Git 忽略文件列表,指定哪些文件和目录不应该被版本控制系统跟踪。package.json: 项目配置文件,包含项目的依赖、脚本和其他元数据。README.md: 项目的说明文件,通常包含项目的介绍、安装和使用说明。package-lock.json: 自动生成的文件,锁定依赖的版本,以确保项目在不同的环境中安装一致的版本。

React Hooks

hooks是什么?

是react 16.8 引入的功能,允许在函数组件中使用state状态和其他react特性,而无需编写类组件

三个常用的Hook

  • React.useState()
  • React.useEffect()
  • React.useRef()

useState Hook

用于在函数组件中添加状态,返回一个状态变量和一个函数,用于更新这个状态变量

eg(Components/index.jsx):

类式组件写法:

import React from 'react'class Demo extends React.Component {state = {count: 0}add = ()=>{this.setState(state => ({count:state.count+1}))}render () {return (<div><h1>和为{this.state.count}</h1><button onClick={this.add}>点我加1</button></div>)}
}

函数式组件写法:

import React,{useState} from 'react'function Demo(){const [count,setCount] = useState(0)const [sex,setSex] = useState('女')const [name,setName] = useState('小白')function add(){// console.log('点击');// setCount(count+1) //第一种写法setCount(count => count+1) //第二种}function changeSex(){setSex(sex => (sex === '男'? '女': '男'))}function changeName(){setName(name => name="小黑")}return (<div><h1>和为:{count}</h1><h2>我是:{name}</h2><h2>性别:{sex}</h2><button onClick={add}>点我加1</button><button onClick={changeName}>点我改姓名</button><button onClick={changeSex}>点我改性别</button></div>)
}export default Demo

上述代码中useState(initialState):

  • useState是一个函数,他接受一个初始状态initialState作为参数
  • 返回一个数组,数组第一个元素是当前的状态值,第二个元素是一个函数,用于更新状态

setXXX()两种写法:

  • setXXX(newValue):参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值
  • setXXX(value => newValue):参数为函数,接收原来的状态值,返回新的状态值,内部用其覆盖原来的状态值

useEffect Hook

用于处理副作用操作(数据获取、订阅、手动操作DOM等)。允许在函数组件中执行这些副作用操作,而不需要使用类组件的生命周期。

  • 类式组件写法:
import React from 'react'
import ReactDOM from 'react-dom'
import root from '../../index'// 类式组件
class Demo extends React.Component {state = {count: 0}  add = ()=>{this.setState(state => ({count:state.count+1}))}unmount = ()=>{if(root){root.unmount()}}componentDidMount(){// console.log('组件挂载完成')this.timer = setInterval(()=>{this.setState(state => ({count:state.count+1}))},1000)}componentWillUnmount(){// console.log('组件将要卸载')clearInterval(this.timer)}render () {return (<div><h1>和为{this.state.count}</h1><button onClick={this.add}>点我加1</button><button onClick={this.unmount}>卸载</button></div>)}
}
export default Demo
  • 函数式组件写法:
import React,{useEffect,useState} from 'react'
import ReactDOM from 'react-dom'
import root from '../../index'function Demo(){const [count,setCount] = useState(0)// useEffect(()=>{//   console.log('-----');    // },[count])
/*   注意:上面的空数组,表示谁也不监测。不写的话就是全都监测(组件挂载和更新都会监测到)具体监测到什么就写什么,比如[count] 就只监测count*/useEffect(()=>{let timer = setInterval(()=>{setCount(count => count+1)},3000)return ()=>{clearInterval(timer)}},[])function add(){setCount(count => count+1)}function onmount(){if(root){root.unmount();}}return (<div><h1>和为:{count}</h1><button onClick={add}>点我加1</button><button onClick={onmount}>卸载</button></div>)
}
export default Demo

useRef Hook

类式组件写法:

import React from 'react'
import root from '../../index'// 类式组件
class Demo extends React.Component {state = {count: 0}  myRef = React.createRef()add = ()=>{this.setState(state => ({count:state.count+1}))}show = ()=>{alert(this.myRef.current.value)}unmount = ()=>{if(root){root.unmount()}}componentDidMount(){// console.log('组件挂载完成')this.timer = setInterval(()=>{this.setState(state => ({count:state.count+1}))},1000)}componentWillUnmount(){// console.log('组件将要卸载')clearInterval(this.timer)}render () {return (<div><h1>和为{this.state.count}</h1><input type="text" ref= {this.myRef} /><button onClick={this.add}>点我加1</button><button onClick={this.unmount}>卸载</button><button onClick={this.show}>弹窗显示数据</button></div>)}
}

函数式组件写法:

import React,{useState,useEffect,useRef} from 'react'
import root from '../../index'function Demo(){const [count,setCount] = useState(0)const myRef = useRef()useEffect(()=>{let timer = setInterval(()=>{setCount(count => count+1)},3000)return ()=>{clearInterval(timer)}},[])function add(){setCount(count => count+1)}function onmount(){if(root){root.unmount();}}function show (){alert(myRef.current.value)}return (<div><h1>和为:{count}</h1><input type="text" ref = {myRef} /><button onClick={add}>点我加1</button><button onClick={onmount}>卸载</button><button onClick={show}>点我显示输入框信息弹窗</button></div>)
}export default Demo

遇到的问题:

问题1:useEffect生命周期函数为什么会被进行两次调用?

问题分析:

这部分代码,我看到控制台--------打印了两次,其原因是react的严格模式会在开发环境下对某些生命周期函数(包括useEffect)进行两次调用,这是为了验证副作用的影响,生产模式不会发生这种情况

解决方法:

在indedx.js入口文件中,删除或者注释掉React.StrictMode即可

问题2:react组件卸载报错问题,如下:
报错显示及分析:
  • unmountComponentAtNode is deprecated and will be removed in the next major release. 报错提示是因为unmountComponentAtNode已经被弃用
  • You are calling ReactDOM.unmountComponentAtNode() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?尝试用旧的卸载方法 ReactDOM.unmountComponentAtNode() 去卸载一个之前使用新的 ReactDOM.createRoot() 方法创建的 React 根节点。这两者是不兼容的。
  • unmountComponentAtNode(): The node you're attempting to unmount was rendered by React and is not a top-level container. Instead, have the parent component update its state and rerender in order to remove this component.你试图卸载的节点不是一个顶层容器节点。换句话说,你可能在试图卸载由 React 管理的子组件,而不是根节点。
解决方法:

通过将root导出并在其他地方导入来管理卸载组件,这是因为直接管理root对象是因为它提供了对react根结点更好的控制,尤其是在react18及以上版本时。他确保能正确地卸载和管理组件,而不会引发错误或与旧版本产生冲突

操作步骤:
  • 在入口文件index.js导出root:
export default root;
  • 在要卸载的组件文件中导入root:
import root from '../../index' //根据自己路径调整function onmount(){if(root){root.unmount();}}<button onClick={onmount}>卸载</button>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

GAugLLM论文阅读笔记

GAugLLM: Improving Graph Contrastive Learning for Text-Attributed Graphs with Large Language Models论文阅读笔记 Abstract 现存的问题: ​ 文本属性的长度和质量往往各不相同,因此很难在不改变原始语义的情况下扰乱原始文本描述。其次,虽然文本属性与图结构互为补充,…

Ceph Reef(18.2.X)之对象访问策略配置

作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 目录一.对象存储概述1.对象存储的访问方式2.基于http方式访问对象存储注意事项3.查看存储桶默认策略二.定制策略1.定制访问策略文件2.应用访问策略3.应用跨域规则【可选操作】三.对象存储的其他访问方式1.基于…

unity学习笔记(二)

2D渲染 Camera相机设置 Projection(投影方式):修改为Orthographic(正交) Size:改变相机的视野大小 Sprite “精灵图”一词首次作为图形术语出现,是在德州仪器的9918(A)视频显示处理器上。使用“精灵图”作为术语,是因为精灵图并不是帧缓冲中位图数据的一部分,而是“悬…

c#学习笔记(一)

基础语法 文档注释&代码块/// <summary>/// 待机/// </summary>#region 物体移动sq.transform.Translate(new Vector3(5,0,0));#endregion字符串格式化输出 使用 $ 可进行格式化输出 C# string 字符串的前面可以加 @(称作"逐字字符串")将转义字符(…

Linux 中实现按照每一列的类别计算 指定列值的平均数

001、[root@PC1 test]# ls a.txt [root@PC1 test]# cat a.txt ## 测试数据如下 a 8 a 3 b 2 e 2 d 10 b 3 b 7 e 4 [root@PC1 test]# awk {ay[$1] += $2; ay2[$1]++} END {for (i in ay) …

广受欢迎文档管理系统有哪些?这10款不容错过

比较好用的 10 款文档管理系统推荐:PingCode、Worktile、语雀、联想Filez企业网盘、360亿方云、DocuPhase 、M-Files 、LogicalDOC、Revver、Box。在现代企业环境中,管理大量文档和数据往往让人头疼。不仅需要维护信息的更新和可访问性,还要确保安全和遵守法规。这使得选择一…

Web刷题之polarctf靶场(1)

PolarCTF 1.XFF打开靶场发现需要ip为1.1.1.1的用户才行, 打开BurpSuite进行抓包并对数据包进行修改,根据题目XFF提示flag{847ac5dd4057b1ece411cc42a8dca4b7}对此题所考察的知识进行一个扩展(对于构造本地用户语句) X-Forwarded-For:127.0.0.1X-Forwarded:127.0.0.1Forwarded-F…

丽水人社公需科目刷课脚本-JavaScript编写

脚本 学习网站:rlzy.lshrss.cn/Service/Index 脚本地址:丽水市专业技术人员继续教育公需科目-刷课脚本 教程 1.插件安装(以Microsoft Edge浏览器为例)打开最中间那个蓝色绿色的浏览器,谷歌之类的浏览器也可以点击屏幕右上角三个点,图示位置,然后点击扩展点击获取扩展搜索…