React中Hook详解

React中Hooks是什么?

Hook是React 16.8.0版本新增的新特性/新语法

可以让你在函数组件中使用state以及其它的React特性

import React,{use...} from 'react'

常用Hook:
useState :
接受一个参数: 就是初始化state的状态

	声明一个数组: 
		
		第一个: state的状态
		
		第二个: 修改state的方法
export default function Test (){
    const [count, setCount] = useState(0)
    return <div>
        {count}
        <button onClick={()=>setCount(count+1)}>操作state</button>
    </div>
}

useEffect

useEffect Hook:
		默认第一个参数:接受一个函数,类似于生命周期,componentDidMount 和 componentDidUpdate

			useEffect(()=>{ console.log("这是Hook") })

		默认第二个参数:如果默认接受一个数组[],如果数组为空 效果 == componentDidMount
		 数据更新就不触发上面方法

		数组里可以接受你要数据更新监听的参数,如果更新状态就触发第一个参数的方法

			useEffect(()=>{ console.log("这是Hook") },[  ])
		
		在第一个参数方法的返回值 == componentWillunmount()
useEffect(()=>{ console.log("这是Hook") }return /* 做一些收尾工作 */), [ count ]}
export default function Test (){
    const [count, setCount] = useState(0)

    useEffect(()=>{
        console.log("这是Hook")
        return /* 做一些收尾工作 */
    },[count])
    return <div>
        {count}
        <button onClick={()=>setCount(count+1)}>操作state</button>
    </div>
}

useRef

useRef:类似于createRef 

const testRef = useRef()

<div ref = { testRef }></div> 
import React,{useState,useEffect,createRef, useRef} from 'react'

export default function Test (){

    const [count, setCount] = useState(0)
    
    const testRef = useRef()
    
    useEffect(()=>{
    
        testRef.current.style.color = "red"
    
    //通过ref选中DOM来操作样式
    
        return /* 做一些收尾工作 */
    
    },[count])
    
    return <div>
    
        {count}
    
        <button onClick={()=>setCount(count+1)}>操作state</button>
        <div ref = {testRef}>
    
            选中这个区域的Hook
    
        </div>
    </div>
}

============================================================
React优化 Frament

import React,{ Frament, Component } from "react"


export default class Test extends Component {
    // render(){
    //     return <>
    //         这是测试函数
    //     </>
    // }

两种方法都是不显示标签,但是空标签不可以接收属性====

    render(){
        return <Fragment key={123}>
            这是测试函数
        </Fragment>
    }

}

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。

类式组件的context

如果要使用创建的上下文,需要通过 Context.Provider 最外层包装组件,并且需要显示的

通过 <MyContext.Provider value={{xx:xx}}> 的方式传入 value,指定 context 要对外暴露的信息。

const Mycount = React.createContext("默认值")
const {Provider} = Mycount
只要是它的子孙组件都可以接收到传递的数据
static contextType = Mycount
import React,{Component} from 'react'
import Fnt from '../Fnt'
import Fnf from '../Fnf'
const Mycount = React.createContext("默认值")
const {Provider} = Mycount
export default class Fno extends Component {
    render(){
        return <div>
            这是第二个组件
            <Provider value={"我传的数据"}>
            <Fnx></Fnx>
            </Provider>
        </div>
    }
}

函数式 useContext

使用const theme = useContext(Mycount) 来接受数据

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


const Mycount = React.createContext("默认值")
const {Provider} = Mycount
export default function Fno (){
        return <div>
            这是第二个组件
            <Provider value={"我传的数据"}>
            <Fnx></Fnx>
            </Provider>
        </div>
}

export function Fnx(){
    return <div>
            我是子组件
           <Fne></Fne>
      </div>
}

export function Fne(){
    const theme = useContext(Mycount);
    return <div>
        {console.log(theme)}
            我是FNe子组件
      </div>
}
//如果是跨页面的组件 需要将*React*.createContext创建的实例对象暴露出去

export const ThemeContext = *React*.createContext("传递的默认数据");

export default function Test() {

  let { Provider } = ThemeContext

  return <div>

?    这是最大的组件

?    <*Provider* *value*={"我传入的我爱你"}>

?      <*Fn1*></*Fn1*>

?    </*Provider*>

  </div>

}

usecallback 返回一个函数 usememo 返还具体的值

useMemo 和 useCallback 接收的参数都是一样,

	第一个参数为回调 
	第二个参数为要依赖的数据

共同作用:

1.仅仅 依赖数据 发生变化, 才会重新计算结果,也就是起到缓存的作用。

      两者区别:
      
		1.useMemo 计算结果是 return 回来的值, 主要用于 缓存计算结果的值 ,
              应用场景如: 需要 计算的状态 
             (返还回来的是值)

	
	    2.useCallback 计算结果是 函数, 主要用于 缓存函数,
	     (返还回来的是函数)
	      应用场景如: 需要缓存的函数,因为函数式组件每次任何一个 state 的变化 整个组件 都会被重新刷新,
	      一些函数是没有必要被重新刷新的,此时就应该缓存起来,提高性能,和减少资源浪费。


	      注意: 不要滥用会造成性能浪费,react中减少render就能提高性能,所以这个仅仅只针对缓存能减少重复渲染时
	      使用和缓存计算结果。
import React,{Component,useContext, useState, useCallback,useMemo} from 'react'
import Fnt from '../Fnt/index'


export default function Fno (){
    const [state, setState] = useState(0)
    const [proState, setProState] = useState(123)

    const expensive = useMemo(() => {
        console.log('我被useMemo更新了');
        
        return state;
    }, [state]);
    // expensive返回的是一个数值 每当state更新 就会出发上面方法

    const testHook = useCallback(() => {
        console.log('我被useCallback更新了');
        return proState
    },[proState])()
        
    // 因为testHook 返回的是一个函数,所以需要调用执行 每当proState更新 就会出发上面方法

        return <div>
            这是第二个组件
            {console.log(expensive)}
            {console.log(testHook)}
            <button onClick = {() => {setState(state+1)}}>我要改变state状态</button>
            <button onClick = {() => {setProState(proState+1)}}>我要改变proState状态</button>
            {/* <Provider value={"我传的数据"}>
            <Fnx></Fnx>
            </Provider> */}
        </div>
}

React 中 “插槽”

export default function Fno (){
    return <div>
        这是父组件
        <Fny render={()=>{ return<Fnw></Fnw>}}></Fny>
    </div>
}



export function Fny (props){
    return <div>
        这是子组件
        {props.render()}
        {console.log(props)}
    </div>
}


export function Fnw (){
    return <div>
        这是父组件传给子组件插槽
        
    </div>
}

版权声明:本文为qq_26705343原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。