IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React Hook总结 -> 正文阅读

[JavaScript知识库]React Hook总结

概览

Hook只能在函数组件中调用
在这里插入图片描述
最后两个hook用的不多(我是没用过),这里就不写了

useState

import Reac , {useState} from 'react'

const App = (params) => {
	const [count,setCount] = useState(0)

	const handleClick = () => {
		setCount(1)
		console.log(count) // 打印: 0 ,说明setCount是异步代码

		// 也可以给setCount赋值一个函数
		setCount((count) => {
			console.log(count) // 打印旧的count
			count++
			console.log(count) // 打印新的count
			return count // 返回最新值覆盖count
		})
		
		setCount(count) // 赋的值和原来相同的话,并不会出发组件的重新渲染
	}
	
	console.log(count) // 打印:1 ,这个位置打印可以即时获取count的最新值	

	return (
		<div>
			<div>{count}</div>	
			<button onClick={handleClick}>按钮</button>
		</div>
	)
}

useEffect

常用的hook,不做介绍

useContext

作用:向所有的后代传参

import React, {Component , creatContext} from 'react'

const AppContext = creatContext();

// 类组件,第一种方式,通过函数消费祖先传过来的value
class Foo extends Component {
	render(){
		return (
		<AppContent.Consumer>
			{value => <div>{values}</div>}
		<AppContent.Consumer>
		)
	}
}

// 类组件,第二种消费祖先传过来的值的方式
class Bar extends Component {
	static contextType = AppContext
	render(){
		const value  = this.context
		return (
			<div>{value}</div>
		)
	}
}


// 以上的两种方式只能用于类组件,函数组件用useContext来消费祖先传过来的值
// 函数组件
const Baz = () => {

	const value = useContext(AppContext)
	
	return (
		<div>{value}</div>
	)
}

const Middle = () => {
	return (
		<div>
			<Foo />
			<Bar />
			<Baz />
		</div>
	)
}

const App = (params) => {
	return (
	<AppContext.Provider value='fanghui'>
		<Middle />	
	<AppContext.Provider>
	)
}

useReducer

作用:处理一些复杂的更加复杂的state运算

import Reac , { useReducer } from 'react'

const App = (params) => {

	const countReducer = (action,state) => {
		switch(action.type){
			case 'add':
				return state + 1
			case 'sub':
				return state - 1
			default:
			   return state
		}
	}
	
	const [count,dispatchCount] = useReducer(0)

	const add = () => {
		dispatchCount({type:'add'})
	}

	const sub = () => {
		dispatchCount({type:'sub'})
	}
	
	return (
		<div>
			<div>{count}</div>	
			<button onClick={add}>1</button>
			<button onClick={sub}>1</button>
		</div>
	)
} 

useMemo 和 useCallback

一种性能优化的手段

import React, { useState, useMemo, useCallback, memo } from "react"

// memo 的作用可以对前后传来的props进行浅比较,如果没有改变则不会重新渲染,如果改变则重新渲染
const Foo = memo(props => {
  console.log("Foo render");
  return (
    <div>
      <ul>{props.render()}</ul>
      {props.count}
    </div>
  )
})

const App = () => {
  const [range, setRange] = useState({ min: 0, max: 10000 });
  const [count, setCount] = useState(0);

  // 返回值render是一个函数,它的引用只会在依赖项发生改变的时候,才会改变
  const render = useCallback(
    params => {
      let list = [];
      for (var i = 0; i < range.max; i++) {
        list.push(<li key={i}>{i}</li>);
      }
      return list;
    },
    [range]
  );

  // 返回值是函数执行后的结果,函数的执行只会在依赖项发生改变的时候,才会再次执行
  // const render = useMemo(
  //   params => {
  //     let list = [];
  //     for (var i = 0; i < range.max; i++) {
  //       list.push(<li key={i}>{i}</li>);
  //     }
  //     return list;
  //   },
  //   [range]
  // );

  //useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

  return (
    <div>
      <h1>{count}</h1>
      <button
        onClick={() => {
          setRange({
            ...range,
            max: range.max + 1
          });
        }}
      >
        add
      </button>
      <Foo render={render}></Foo>
    </div>
  );
}

useRef

提到useRef,我们不得不再提下creatRef

  1. 都可以获取原生DOM
import Reac , { creatRef, useRef } from 'react'

const FuncComp = (params) => {

	// 可以用creatRef创建ref容器,creatRef同样适用于类组件
	const inputRef = creatRef()
	// 也可以用useRef创建ref容器,useRef只能用在函数组件
	const inputRef = useRef()

	// 当我们每次更新state时,组件会重新渲染,我们发现通过creatRef创建的ref每次的引用都是不同的
	// 而useRef创建出来的ref的引用都是相同的
	// 建议在类组件里使用creatRef,函数组件里使用useRef,这样可以提高性能
	
	return (
		<div>
			<input ref=() />	
			<button onClick={inputRef}>聚焦</button>
		</div>
	)
} 
  1. useRef和creatRef的区别

当子组件是类组件时

import Reac , { creatRef, useRef,Component } from 'react'

class ChildClassComp extends Component {
	
	const inputRef = creatRef()
	
	focusInput = () => {
		inputRef.current.foucs()
	}
	 
	render(){
		return (
				<div>
					<input ref={inputRef} />	
					<button onClick={focusInput}>聚焦</button>
				</div>
			)
	}
}

class ClassComp extends Component {

	// 当我们用creatRef绑定在类组件身上时,可以获取到类组件的实例
	const childRef = creatRef()

	conponentDidMount(){
		//调用类组件身上的方法
		childRef.current.focusInput()
	}
	
	render(){
		return (
				<div>
					<ChildClassComp  ref={childRef}/>	
					<button onClick={inputRef}>聚焦</button>
				</div>
			)
	}
	
} 

当子组件是函数组件时

import Reac , { creatRef, useRef,Component,forwordRef } from 'react'

const ChildFuncComp = forwordRef ((props,ref) => {
	
	return (
			<div>
				<input ref={ref} />	
				<button onClick={focusInput}>聚焦</button>
			</div>
		)
})

class ClassComp extends Component {

	const childRef = creatRef()

	conponentDidMount(){
		//转发 refs 到子组件 DOM 组件
		childRef.current.focus()

		// ref绑定的子组件是函数组件时,无法像绑定类组件一样直接获取类组件的实例
		// 而且函数组件时不允许绑定ref的,否则控制台会报错,我们需要用forwordRef包裹一下
		// 然后转发ref绑定函数子组件的DOM元素
	}
	
	render(){
		return (
				<div>
					<ChildClassComp  ref={childRef}/>	
					<button onClick={inputRef}>聚焦</button>
				</div>
			)
	}
	
} 

刚学的时候,还是蛮绕的,通过Js++集团得小夏老师的讲解终于弄懂了,感谢 !

总结 :

  1. creatRef创建ref容器,既可以绑定类组件也可以绑定函数组件,但是当函数组件每次重新渲染时,它所创建的ref的引用都是新的,所以我们在函数组件里更推荐使用useRef,它每次创建出来的ref的引用都是一样的,性能更高。而类组件里别无选择,只能使用creatRef,它也只会在类组件里执行一次,ref的引用都是一样的。
  2. 不论是useRef还是creatRef创建出来的ref绑定在类组件身上的时候,获取的是绑定类组件本身的实例,而当绑定的是函数组件的时候,只能使用forwordRef来转发到函数子组件里的具体DOM元素(我记的别的文章也叫穿透ref)

useImperativeHandle

前提:学会这个useImperativeHandle前,你需要学会useRef这个hook

作用:在项目中,别人调用我们写的子组件时,需要知道我们这个子组件所暴露给父组件的实例值,useImperativeHandle 应当与 forwardRef 一起使用

import Reac , { creatRef, useRef,Component,forwordRef } from 'react'

const ChildFuncComp = forwordRef ((props,ref) => {

  const inputRef = useRef()

  useImperativeHandle(ref,() => {
	return {
		customerFocus: () => {
      		inputRef.current.focus();
    	},
    	sayHello: () => {
    		console.log('Hello World')
		}
	}
  })
	
	return (
			<div>
				<input ref={inputRef} />	
				<button onClick={focusInput}>聚焦</button>
			</div>
		)
})

class ClassComp extends Component {

	const childRef = creatRef()

	conponentDidMount(){
		childRef.current.customerFocus()
		childRef.current.sayHello()
	}
	
	render(){
		return (
				<div>
					<ChildClassComp  ref={childRef}/>	
					<button onClick={inputRef}>聚焦</button>
				</div>
			)
	}
	
} 

未完,待续…(可能)

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 01:54:55  更:2022-09-15 01:56:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:05:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码