首页 > 其他分享 >react创建项目&&常见的三大Hook

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

时间:2024-09-01 22:47:37浏览次数:13  
标签:count React react Hook state && 组件 root

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.png
    log512.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>

标签:count,React,react,Hook,state,&&,组件,root
From: https://www.cnblogs.com/sharenotes/p/18391892

相关文章

  • react常用 Hooks
    ReactHooks是React16.8引入的一项功能,它允许你在函数组件中使用状态和其他React特性,而不需要编写类组件。Hooks使函数组件可以管理本地状态、处理副作用、使用上下文等,使得函数组件更加强大和灵活。以下是常用的ReactHooks及其使用方法:useStateimportReact,{us......
  • 【React】React事件和HTML事件的区别
    React写法<buttononClick={handleClick}>测试</button>HTML写法<buttononclick="handleClick()">测试</button>区别ReactHTML原生事件绑定方式小驼峰命名法,事件处理函数通过JSX语法直接绑定全小写形式定义事件处理函数函数引用内联的字符串表达式事件对象基于Ev......
  • 【vue3】探讨为什么ref()换为reactive()数据不再是响应式?
    原问题:本来想使用数组中的filter方法,原来用的是lettableData=ref([])然后发现Ref上不再filter属性,所以就换成了lettableData=reactive([])但是这样有了一个新问题就是:数据加载不出来了,代码如下//获取文章列表数据 lettableData=reactive([]) functiongetArt......
  • 13.JS学习篇-ES6 React 项目模板
    1.项目能力支持1.项目初始化脚手架1.前端编码规范工程化(lint工具、NodeCLI等)2.用工具提升项目的编码规范,如:eslint、stylelint、commitlint、markdownlint、husky等3.工具对于JavaScript、Typescript、React、Vue等不同类型的前端项目下的标准的语法限制;2.相关基础功能......
  • 【Linux网络编程】Reactor模式与Proactor模式
    【Linux网络编程】Reactor模式与Proactor模式Reactor模式Reactor模式是指主线程即IO处理单元只负责监听文件描述符上是否有事件发生,有则立刻将该事件通知给工作线程即逻辑单元,除此之外,主线程不做任何其它实质性的动作。读写数据,接受新的连接,以及处理客户请求均在工作线程中完......
  • vue3 自定义hooks(组合式函数)
    什么是hooks自定义hooks是Vue3组合式函数的别称。在Vue应用的概念中,“组合式函数”(Composables)是一个利用Vue的组合式API来封装和复用有状态逻辑的函数。命名规范组合式函数约定用驼峰命名法命名,并以“use”作为开头。以便识别它们是可复用的逻辑单元。例如,u......
  • React 高德地图 进京证 (二)
    上回书说到,躲开摄像头的基本功能实现了,但有三个核心问题:(1)速度慢(2)距离远易失败(3)地图限制第一个问题:较为简单,把几千个摄像头按行政区划分好带上编号,在路线分段避让时按片儿计算,综合测试速度提升了50%。//找到每段step途径的letwayDistrictsCamera=[];step.cities.map(city......
  • vue3写一个触底加载hook
    天行健,地势坤--《周易·象传》背景:在一个滚动容器下实现触底加载更多的函数,由于此模块使用的场景较多,因而自己实现了一个滚动加载的hook(顺带尝试了下hook)需求:左侧tab切换时,右侧聊天历史tab要清空并重新请求;右侧触底时,要触发分页请求(如果有);使用dayjs中的fromnow方法以精确体......
  • react面试题八
    一、如何优化React应用的性能?优化React应用的性能是一个多方面的过程,涵盖了从代码优化到应用架构调整等多个方面。以下是一些关键策略和技术,可以帮助你提升React应用的性能:1.代码拆分和懒加载代码拆分:将代码分割成更小的块,然后只加载当前路由或页面需要的代码块。这可......
  • react面试题九
    一、ReactRouter是如何实现单页应用的路由管理的?ReactRouter实现单页应用(SPA)的路由管理主要通过以下方式:一、路由模式ReactRouter提供了多种路由模式来适应不同的开发需求,其中主要的两种模式是HashRouter和BrowserRouter。HashRouter:使用URL的哈希部分(即#......