react-hook学习

hooks技术不是一门新的技术,而是一种设计思想。

自定义hooks更像是一种约定,而不是一种功能,一般以use开头的,并调用其他hook,就可以称为自定义Hooks(自定义的Hook中,最里面一定是使用了useEffect函数)。

注意:

每次调用 setSate的类似函数(例如:setCount),都会从新执行整个函数组件。

useState()

const [count, setCount] = useState(0);
/*
初始化一个状态变量并带有初始值(0)
	count:初始化的状态变量
	setCount:改变这个状态的函数(类似与setState())
*/

useContext()

在类组件中有constructor函数,可以用来接收pops属性的值。

但是函数式组件中没有constructor函数,也就没有了接受props属性的地方,那么在这种情况下父组件想向子组件传值就有问题了,为了解决这个问题,引入了useContext()函数。

作用:

  • 实现跨越组件层级传递变量,提供全局共享。

    useContext()解决组件之间传递的问题。与useReducer()配合使用,可以实现类似于redux的功能。

    redux整个应用中统一状态管理。

  • context是对它所包含的组件树提供全局共享数据的一种技术。

cont [state, dispatch] = useContext(context)
/*
useContext(context)
接收一个context参数,这个context是由React.createContext(defaultValue)所创建的
*/

const {Provider, Consumer} = context = React.createContext(defaultValue);
function Parent(){
    const [count, setCount] = useState(0);
    return(
    	<>
        	<div>{count}</div>
        	<button onClick={()=>{setCount(count+1)}}>Click Me</button>
        	<Provider value={count}>
        		<Child />
        	</Provider>
        </>
    )
}

function Child(){
    const count = useContext(context);
    return (<h2>{count}</h2>)
}
/*
既然是解决父组件想子组件传值的问题的,那么父组件是如何向子组传递值的呢?
1. 父组件需要把将要传递的值放到context中
2. 子组件使用useContext()获取父组件传递的值

//定义一个父组件最外层的context变量(可以单独成文件,然后再父组件和子组件中分别引入使用)
const {Provider, Consumer} = context = React.createContext(defaultValue);
	Provider是传值方(context.Providert)
	Consumer是接收方(context.Consumer)

function Parent(){
    const [count, setCount] = useState(0);
    return(
    	<>
        	<div>{count}</div>
        	<button onClick={()=>{setCount(count+1)}}>Click Me</button>
        	
        	//将父组件要传递的值放入到context中
        	<Provider value={count}>
        		//这样父组件中的count发生变化后,子组件的值就会发生改变
        		<Child />
        	</Provider>
        </>
    )
}

//重点 重点  重点
function Child(){
	//使用useContext()接收父组件传递过来的属性值,这里useContext会获取到离子组件最近的父组件传递过来的值
	//同时需要注意的是,这里的context必须要与父组件是相同的context,才可以实现数据的共享。
    const count = useContext(context);
    return (<h2>{count}</h2>)
}
*/

useEffect(func,[deps])

相当于类组件中的componentDidMount()componentDidUpdate()以及componentWillUnmount()的合并,即完成DOM修改后的调用函数

func:表示DOM渲染后需要执行的函数体。

deps:表示这个useEffect()的依赖项,依赖项发生改变,就会再次执行func函数体。

useEffect()如果函数中由需要清除的副作用,就需要在useEffect()函数体内返回一个函数

useEffect(()=>{
    //....
    return ()=>{
        //需要清除的副作用
    }
},[])

useReducer(reducer,initState)

useReducer(reducer,initState)用来管理state状态(多个状态需要同时修改时,建议使用:例如:登录验证)

import React,{useReducer} from 'react'

export default function ReducerDemo() {
    const [count, dispath] = useReducer((state,action)=> {
       switch(action){
           case 'add':
                return state + 1;
            case 'sub':
                return state - 1;
            default:
                return state;
       }
    }, 0);
    return (
        <div>
            <h1 className="title">{count}</h1>
            <button className="btn is-primary"
                onClick={()=> dispath('add')}
                >Increment</button>
            <button className="btn is-warnning"
                onClick={()=> dispath('sub')}
                >Decrement</button>
        </div>
    )
}

/*
const [count, dispatch] = useReducer(reducer,initState)
	reducer: 一个负责改变state的值的函数,
		这个函数由两个参数:reducer(state,action)
			state:初始状态
			action:reducer函数会根据action的类型来判断将怎么改变这个state
	count:状态改变后的值
	dispatch:一个触发reducer的机制,在组件中调用。(重要)
	
	
	return [
		...state,
		{
			id:10,
			name:"haha"
		}
	]
	这句话的意思是,先copy一个state,然后修改这个state
*/

useRef(initValue)

const like = useRef(0);
//贯穿组件的整个生命周期,组件重新渲染后like的值不会改变,保持原值。

useLayoutEffect(func,[deps])

布局副作用:

​ useEffect在浏览器渲染完成后执行

​ useLayoutEffect在浏览器渲染完成前执行

特点:

​ useLayoutEffect总是比useEffect先执行

​ useLayoutEffect里面的任务最好影响layout(布局)

注意:

​ 最好是使用useEffect(为了用户体验最好)

useCallback(func,[deps])

解决:函数组件的每一次调用都会执行其内部的所有逻辑,那么会带来较大的性能损耗。

useMemo()useCallback()就是解决这些问题的杀手锏。

  • useMemo() 返回缓存的变量
  • useCallback() 返回缓存的函数
const funA = useCallback(funcB, [deps]);
//将传递进来的funcB返回给funcA,并且将这个结果进行缓存,如果依赖改变了,就会返回新的函数。

注意:

useMemo(),useCallback(),useEffect()都是自带闭包的,即组件每次重新渲染,其都会捕获当前组件函数上下文中的状态(stat,props),所以它反映的也都是组件当前的状态。

useMemo(initValue)

类似与useCallback,只是useMemo返回的是缓存的变量。

const valueA = useMemo(2);
//valueA变量会一直保留,重新渲染组件时不会重新定义这个变量。

posted @ 2021-10-16 22:57  依梦维马  阅读(70)  评论(0)    收藏  举报