React 最新版本(hooks写法)

React 目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • React 目录
  • 前言
  • 一、指令
        • jsx语法:
          • 需要注意的是:react的类名class变成了 className,事件从onClick,因为class是react的内部关键字
        • 动态数据
          • useState() 相当于Vue3的ref(),reactive()
        • 条件渲染
        • 列表渲染
        • 动态样式
        • 双向数据绑定
        • 事件处理
          • 给元素添加事件
          • 事件传递参数
          • 事件对象
          • 阻止事件冒泡
  • 二、组件
        • 组件创建
          • class组件=〉16.8之前的版本
          • 函数式组件(当前推荐)
        • react组件的组合
        • react组件声明
        • 组件数据传递(和Vue3大体相同)
          • 父组件给子组件数据,通过属性的方法,子组件通过props接收
          • 子组件给父组件数据=》本质就是方法的调用和方法的声明
          • 本地存放数据
          • redux或者react/toolkit
          • useContext和Vue中的provider,inject =》全局变量
        • 组件的生命周期
          • 函数组件
          • class组件
    • 三.hooks
        • useState()
        • useEffect
          • watch
        • useContext
        • useReducer
        • useRef
        • useLayoutEffect
        • useMemo
        • React.memo
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

在我理解,每个框架都可以分为这六大类:指令,组件,属性,hooks,路由,全局存放数据。


提示:以下是本篇文章正文内容,下面案例可供参考

一、指令

jsx语法:

什么是jsx,jsx就是html和js结合

需要注意的是:react的类名class变成了 className,事件从onClick,因为class是react的内部关键字
动态数据
useState() 相当于Vue3的ref(),reactive()

useState(). 基本数据类型。 对象数据。 数组数据。

在 hooks中操作的对象数据类型,不会合并原来的数据

import {useState} from "react"

function App() {


  let [age,setAge] = useState(10)

  const addAge = ()=> {
    setAge(age+1)
  }


// 复杂数据  =》 数组
  let [list,setList] = useState(['1','2'])

  const reduces = (index)=> {
    setList((state)=> {
      state.splice(index,1)
      return [...state]
    })
  }


  // 复杂数据 对象
  let [stateObj,setState] = useState({name:'虎',age:12})
  const changeAge = ()=> {
    setState((state)=> {
      return { // 返回的就是新的数据
        ...state,
        age: state.age+1
      }
    })
  }

  return(

    <div>
      <h1>{age}</h1>
      <button onClick={()=>addAge()}></button>

      {
        list.map((item,index)=> {
          return <div key={index}>{item} .  <button onClick={()=>reduces(index)}></button></div>
        })
      }


      <h2>{stateObj.name}</h2>
      <h2>{stateObj.age}</h2>

      <button onClick={()=>changeAge()}>change</button>
    </div>
  )
  
}

export default App
条件渲染

//条件渲染

// 判断条件

// 写法1=》在模块中使用  {} 处理

// 写法2=》在组件的逻辑层中进行处理
function App(){
    let nums = 60



    //逻辑层

    function getNum(){
           if(nums>=60){
            return <div>及格</div>
           }else{
            return <div>不及格</div>
           }
    }
    return (
        <div>

            {/* 写法 1 用户   =》{} */}
            {nums>=60?<div>及格</div>:<div>不及格</div>}

            {getNum()}
        </div>
    )
}



export default App
列表渲染


//  列表循环  和添加key 

//写法  

//1写法1 在模块中通过  展示动态数据  {}  在这里写  map 

//2 写法2  在逻辑层已经处理好 循环 =》 通过  map

//3 需要同key => react  更新 识别元素的唯一标识=》底层diff

//注意 =》jsx 类名  =>className
function App(){
     let list = ['西瓜','桃子','葡萄']
      
     let lists = [1,2,3]
     
     //map 循环 =》 特点 =》 如果  有  return  返回我们需要 数据 =》创建创建一个数组
        // let arrs = lists.map(item=>{
        //        console.log(item);
        //        if(item>2){
        //         return item
        //        }
           
        // })
        // console.log(arrs);

        // key=> react  要走 diff 算法 =》根据这个key 来判断 是否是同一个元素

        // 写法2

       function getLists(){
        return  lists.map((item,index)=>{
                return (
                    <div key={index}>{item}</div>
                )
              } )
              
        }
    return (
        <div className="list">
             {/* 写法1 */}
           {
            list.map((item,index)=>{  //item
                 
                return(
                    <div key={index}>{item}</div>
                )
            })
           }
           
           {/* 写法2 */}
           <div>    
                {getLists()}

           </div>
        </div>
    )
}


export default  App
动态样式
属性={三元运算符}
双向数据绑定

import {useState} from 'react'


//在react  中 我们把 获取到用户的数据 组件,他的数据 是由 react  数据决定的 叫做 受控组件
function App() {

//逻辑层
  let [value,setValue]= useState('')

  const getInputData = (e)=>{
         console.log(e.target.value);
         setValue(e.target.value)
  }
    return (
        <div>
            {/* 获取到用户的数据时候 
            1:在逻辑层可以获取到用户的数据
            2:传递到 逻辑层
            
            */}
            <h2>  双向数据绑定</h2>
         {/*  双向数据绑定的原理 
         1: 要知道  from  表单系列的元素他有一个属性  value
         2: 结合   from  表单系列的元素 input  change
         3:  结合事件对象  
         */}
         <div>
            用户名:<input value={value} onInput ={(e)=>getInputData(e)}></input>

            <h2>{value}</h2>
         </div>
        </div>
    )
}


export default App
事件处理
给元素添加事件

on事件类型 =》 高阶函数 (react底层代码中有一个事件合成机制,在模版编译时将jsx语法变成虚拟DOM,我们的jsx语法中写事件处理,会将所有的事件集中执行第一层)

事件传递参数

函数的形参和实参

事件对象

就是高阶函数的第一个参数

阻止事件冒泡

事件对象=》e.staopPropagation()

二、组件

组件创建
class组件=〉16.8之前的版本
函数式组件(当前推荐)
react组件的组合

模块化

react组件声明

首字母大写

组件数据传递(和Vue3大体相同)
父组件给子组件数据,通过属性的方法,子组件通过props接收
子组件给父组件数据=》本质就是方法的调用和方法的声明
本地存放数据
redux或者react/toolkit
useContext和Vue中的provider,inject =》全局变量
组件的生命周期
函数组件
class组件

三.hooks

useState()

1:处理动态数据,相对Vue3的响应式API(ref,reactive),在 hooks中操作的对象数据类型,不会合并原来的数据
2:语法:let [默认值,更新视图的方法] useState(默认值)
3:注意他的默认数据:基本数据类型,复杂数据类型之数组,复杂数据类型之对象
4:react 视图更新机制 =》是通过组件重新创建

import {useState} from "react"

function App() {


  let [age,setAge] = useState(10)

  const addAge = ()=> {
    setAge(age+1)
  }


// 复杂数据  =》 数组
  let [list,setList] = useState(['1','2'])

  const reduces = (index)=> {
    setList((state)=> {
      state.splice(index,1)
      return [...state]
    })
  }


  // 复杂数据 对象
  let [stateObj,setState] = useState({name:'虎',age:12})
  const changeAge = ()=> {
    setState((state)=> {
      return { // 返回的就是新的数据
        ...state,
        age: state.age+1
      }
    })
  }

  return(

    <div>
      <h1>{age}</h1>
      <button onClick={()=>addAge()}></button>

      {
        list.map((item,index)=> {
          return <div key={index}>{item} .  <button onClick={()=>reduces(index)}></button></div>
        })
      }


      <h2>{stateObj.name}</h2>
      <h2>{stateObj.age}</h2>

      <button onClick={()=>changeAge()}>change</button>
    </div>
  )
  
}

export default App
useEffect

1:相对于组件的生命周期:组件加载完毕,组件更新,组件摧毁。语法:useEffect(()=>{},[])空数组相当于onMounted
2:相对watch:语法:useEffect(()=>{},[监听的数据])

相当于组件的生命周期 onMounted 在浏览器生成了DOM结构*

相当于组件的生命周期 updata*

相当于组件的生命周期 摧毁 =》 被摧毁的时候会执行 useEffect(处理函数的返回值,是一个函数)*

这个组件被摧毁了,就会执行这个处理函数*

在下一个useEffect处理函数执行之前执行

工作中用的最多的就是 mounted =》 发送网络请求

*useEffect(()=> {},[]) => mounted => 放了空数组之后就只会执行一次 * 常用来发送网络请求

相当于组件的三个生命周期,相当于watch,相当于

页面级组件 =》 加载完毕 =〉mounted

功能级组件 =》 使用watch =〉 useEffect(()=》 {},[数据源])

import { useEffect , useState} from "react"

// useEffect 
// 相当于组件的生命周期 mounded =》 在浏览器生成了DOM结构
// 相当于组件的生命周期 updata
// 相当于组件的生命周期 摧毁 =》 被摧毁的时候会执行 useEffect(处理函数的返回值,是一个函数)

function App() {

let [age,setState] = useState(9)

const changeAge = ()=> {
  setState(age+1)
}

  useEffect(()=> {
    console.log('浏览器有DOM结构了');
    let dom = document.getElementById('h2')
    console.log(dom);
  })


  return(

    <div>
      <h2 id="h2">你好同学</h2>
      {age}
      <button onClick={()=>changeAge()}></button>

      {
        age==12?<Children1></Children1>: ''
      }
    </div>
  )
}

function Children1() {
  useEffect(()=> {
    return ()=> { // 这个组件被摧毁了,就会执行这个处理函数
      // 在下一个useEffect处理函数执行之前执行
      console.log('我被摧毁了');
    }
  })

  return(
    <div>
      children
    </div>
  )
}

export default App
watch

// useEffect 相当于 Vue添加配置项的 watch
// useEffect(()=> {},[]) => mounted => 放了空数组之后就只会执行一次
import { useEffect, useState } from "react"

function App() {
 let [num,setNum] = useState(1)
const addNum = ()=> {
  setNum(num+1)
}


useEffect(()=> {
  console.log('mounted');
},[])

  return(
    <div>
      <h1>{num}</h1>

      <button onClick={()=>addNum()}>加一</button>

      <ChildrenItem></ChildrenItem>
    </div>
  )
}

function ChildrenItem(props) {

  let [name,setName] = useState('不开心')


  // watch
  useEffect(()=> {
    if(name=='还是不开心') {
      setName('怎么办')
    }
    console.log(1);
  },[name,props.age])

  const changeName = ()=> {
    setName('还是不开心')
  }
  return(
    <div>


<h2>{name}</h2>
      <button onClick={()=>changeName()}>changeN</button>
    </div>
  )
}
export default App
useContext

1:和React.createContext()一起使用
2:本质就是一个全局变量
3:作用:在父组件提供数据,在子组件获取数据
React.createContext() => 提供数据
语法 =》 React.createContext(默认值) =》 返回一个实例对象,有一个属性 provider。
provider,他是一个组件,有一个属性 value 用来在 父组件中提供数据

import React,{ useContext } from "react"

// useContext()
// 相当于全局变量,类似于=> Vue inject
// 使用结合 React.createContext(themes.light) => Vue provider

let themes = {
      light: {
            h1:'11'
      },
      back: {
            h1:'22'
      }
}
let ThemeContext = React.createContext(themes.back) // 返回一个对象实例
// React.createContext(默认值) =》返回对象,其中有一个provider 组件,提供数据,有一个属性Value
// value =》 提供的数据

function App() {


      return(
            <ThemeContext.Provider value={themes.back}>
            <div>
                  <h2>全局变量</h2>
                  <Children></Children>
            </div>
            </ThemeContext.Provider>
      )
}

function Children() {
      // 获取数据
      let value = useContext(ThemeContext)
      console.log(value);
      return (
            <div>
                  <h1>儿子</h1>
                  <Son></Son>
            </div>
      )
}

function Son() {
      let value = useContext(ThemeContext)

      return(
            <h2>孙子</h2>
      )

}

export default App

// 总结 use Context()必须和 React.createContext() 一起使用

// React.createContext() => 提供数据
// 语法 =》 React.createContext(默认值) =》 返回一个实例对象,有一个属性 provider。
// provider,他是一个组件,有一个属性 value 用来在 父组件中提供数据

// 在子级组件中 通过 useContext(React.createContext(默认值)中的默认值)
useReducer

1:useReducer 是 useState的高级处理 =》 本质就是添加了约束*
2:语法 useReducer(reducer,默认数据) 返回值 =》 【默认数据,行为】*
3:reducer=> 就是规定死的操作行为 =》这个 reducer是一个方法*
4:reducer 的参数1: 默认数据 参数2 :行为
5:reducer 的返回值 就是最新的数据
6: useReducer 和 useState 一样,处理动态数据
7:useReducer 有规定的行为
8: useReducer 只能处理同步数据
9: 如果在工作中 useReducer 的 reducer中的行为处理逻辑很多
10:在这个reducer中先定义行为比如:add,delect, 他的逻辑可以中js抽离出去

import { useReducer, useState } from 'react'
// useReducer 是 useState的高级处理 =》 本质就是添加了约束
// 语法 useReducer(reducer,默认数据) 返回值 =》 【默认数据,行为】
// reducer=> 就是规定死的操作行为 =》这个 reducer是一个方法
// reducer 的参数1: 默认数据 参数2 :行为
// reducer 的返回值 就是最新的数据

//  useReducer 和 useState 一样,处理动态数据
//  useReducer 有规定的行为
//  useReducer 只能处理同步数据
//  如果在工作中 useReducer 的 reducer中的行为处理逻辑很多
//  在这个reducer中先定义行为比如:add,delect, 他的逻辑可以中js抽离出去
// function App() {
//       let [num,setNum] = useState(10)
//       const addNum = ()=> {
//             setNum(num+1)
//       }

//       const  changeNum = ()=> {
//             setNum('五')
//       }
//       return(
//             
//

{num}

//
// // //
//
// ) // } let getAdd = (state)=> { return state=state==5?state*2:state+1 } let reducer = (state,action)=> { switch(action.type) { case 'add': return getAdd(state) case 'reduce': return state-1 default: return state } } function App() { let [num,dispatch] = useReducer(reducer,0) return( <div> <h2>{num}</h2> <button onClick={()=>dispatch({type:'add'})}>+</button> <button onClick={()=>dispatch({type:'reduce'})}>-</button> </div> ) } export default App
useRef

作用:获取到真实DOM

1:需要在我们想得到的元素上添加一个属性 ref 注意这个 ref的值=》 就是useRef()这个方法的返回值

2:组件的生命周期 =》 组件的创建中 =》 创建 useRef =》获取到真实DOM

3:在组件挂在完毕中 获取到真实DOM


// useRef => react 获取到真实DOM
// 获取到元素的真实DOM =》 需要在浏览器中有DOM结构
// 使用这个 hoos,需要在我们需要获取的元素上添加一个属性 ref => 这个ref的值是谁
import {useEffect,useRef} from 'react'
function App() {
      // 
      let getH2 = useRef(null)
      useEffect(()=> {
            let dom = document.getElementById('apps')
            console.log(dom);
            console.log(getH2.current.innerHTML = '啊');
      },[])
      return(
            <div >
                  <h2 id='apps' ref={getH2}>你好同学</h2>
            </div>
      )
}

export default App

// 总结: useRef 
//       作用:获取到真实DOM
//             1:需要在我们想得到的元素上添加一个属性 ref 注意这个 ref的值=》 就是useRef()这个方法的返回值
//             2:组件的生命周期 =》 组件的创建中 =》 创建 useRef =》获取到真实DOM
//             3:在组件挂在完毕中 获取到真实DOM
useLayoutEffect

1:useLayoutEffect=> 和 useEffect 用法一样
2:useLayoutEffect 是一个微任务 , useEffect 是一个宏任务。本质 promise 数据过来页面没刷新,防止重绘回流
3:useLayoutEffect(处理函数,依赖项)
4:作用:1: 三个生命周期 =》 加载之前 更新之前 摧毁之前
2: watch


function App() {
      let [age,setAge] = useState(10)
      const addAge = ()=> {
            setAge(age+1)
      }
      useLayoutEffect(()=> { // beforeMounted
            console.log('微任务组件加载');
      },[age])
      useEffect(()=> {
            console.log('宏任务');
      })
      return(
            <div>
                  <h2>{age}</h2>
                  <button onClick={()=>addAge()}>1</button>
            </div>
      )
}
export default App
useMemo

1:useMemo 作用: 缓存组件中的变量
2:用法:useMemo(处理方法,依赖项)=》返回值 处理方法的返回值
3:但是在工作中并不常用,因为发现性能的消耗可能会比不使用更大

import { useState,useMemo } from "react"

// useMemo 作用: 缓存组件中的变量
// 用法:useMemo(处理方法,依赖项)=》返回值 处理方法的返回值

function App() {
      let [age,setAge]= useState(10) // 动态数据
      let text = '您好好同学!' // 组件的属性
      let [money,setMoney] = useState(100)

      // 工作中不写
      let msg = useMemo(()=>{
            return '你好同学'
      },[money])
      console.log('组件重新创建');
      const change = ()=> {
            setAge(age+1) // 数据更新 =》 组件重新创建
      }
      return(
            <div>
                  <h2>{age}</h2>
                  <button onClick={()=>change()}>change</button>
                  {msg}
            </div>
      )
}
export default App
React.memo

1: 在父组件中更新数据
2:在父组件更新数据 =》 在这个父组件中的组件模块重新创建了
3:但是有的数据没改变,不需要重新创建 => 通过React.memo 缓存组件
4:语法:React.memo(处理的组件) =》 返回一个新的组件
5:作用: 缓存组件,如果React.memo处理的功能组件,获取到父组件的数据没改变,就不会重新创建,否则就不会重新创建

import React,{useState} from 'react'

function App() {
console.log('父组件创建');
let text = "9999" // 写变量 也需要做优化,缓存
let [state,setState] = useState({name:'好次',age:19})
// 在父组件中更新数据
// 在父组件更新数据 =》 在这个父组件中的组件模块重新创建了
// 但是有的数据没改变,不需要重新创建 => 通过React.memo 缓存组件
// 语法:React.memo(处理的组件) =》 返回一个新的组件
// 作用: 缓存组件,如果React.memo处理的功能组件,获取到父组件的数据没改变,就不会重新创建,否则就不会重新创建
const changeState = ()=> {
      setState((state)=> {
            return {
                  ...state,
                  name:'qq'
            }
      })
}
      return(
            <div>
                  <h1>react更新机制优化</h1>
                  <h2>{state.name}</h2>
                  <button onClick={()=>changeState()}>change</button>
                  <MeTopItem name={state.name}></MeTopItem>
                  <ContentItem></ContentItem>
            </div>
      )
}

// 头部组件的更新让这个组件重新创建

function TopItem(props) {
      console.log(props);

let [age,setAge] = useState(10)
const addAge =()=> {
      setAge(age+1)
}
console.log('头部组件创建');
      return(
            <div>
                  <h3>头部数据 {age}</h3>
                  <button onClick={()=>addAge()}>age+1</button>
                  {/* 搜索组件,退出组件 */}
            </div>
      )
}
let MeTopItem = React.memo(TopItem)



function ContentItem() {
      console.log('内容组件创建');
      return(
            <div>
                  <h3>内容组件</h3>
            </div>
      )
}
export default App

// react更新机制
// 1: 在功能组件中更新数据,父组件不会重新创建,但会重新创建自己
// 所以必须模块化

总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

你可能感兴趣的:(React,react.js,javascript,前端)