React的Hooks篇介绍(上)

Hooks是什么?

Hooks到底是什么,React从16.8版本,推出了Hooks概念,致力于打造函数+hooks的开发体验。Vue3里也推出了组合式Api,也带来了Hooks的概念。

 常见的Hook有哪些?

1.React

useState

给函数式组件中,添加状态。

import {useState} from 'react'

export default ()=> {
   let [自定义名字,set自定义名字]=useState("初始值")
}

useEffect

模拟生命周期钩子函数

import {useEffect} from 'react'

export default ()=>{
   //第一个参数执行函数,第二个参数不传

   useEffect(() => {

    //调用函数,类似于mounted
     return ()=>{
         //类似于destroyed
     }

   })

   //第一个参数执行函数,第二个参数传空数组[]
   useEffect(()=>{
      console.log('加载完了')
    },[])//这个时候就执行一次
    
   //第一个参数执行函数,第二个参数传state数组
   useEffect(()=>{
       console.log('更新了','当数据变化了就会执行这个函数')
   },[count,name])//第二个参数就是依赖的state

}

useContext

如果我们想要让组建的数据传递给后代组件,可以使用Context,我们需要借助createContext来帮助我们解决问题。

祖先组件

import { createContext } from "react";
import Children from "./children"
export let ZDYContext = createContext({})
const person = () => {
    return (
        // 使用ZDYContext.Provider 包括所有标签
        <ZDYContext.Provider value={{name:'康益凡'}}>
            <div>
                    <Children></Children>
            </div>
        </ZDYContext.Provider>

    );
}

export default person;

子组件

import { useContext } from "react";
import { ZDYContext } from "./person";
const children = () => {
    let context =useContext(ZDYContext)
    return ( 
        // 在后代组件中,我们可以通过useContext获取对应的
        <div>
            你好呀
            <p>{context.name}</p>
        </div>
     );
}
 
export default children;

React组件的渲染机制

当一个React组件中的数据被修改时,那么这个组件就会被重新渲染,只要内部有子组件,子组件也会被重新渲染。

import { useState } from "react";

const Child = () => {
  console.log('Child被渲染')
  return ( 
    <div>
      <h1>Child</h1>

    </div>
  );
}


const Parent = () => {
  console.log("Parent被渲染")
  let [count, setCount] = useState(0)
  return (
    <div>
      <h1>Parent</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <hr />
      <Child></Child>
    </div>
  );
}

当我们的数据count发生改变时,我们对应的Parent会被重新渲染,因为父组件重新渲染了,会导致Child也被重新渲染。

这个时候,我们就可以使用memo包裹我们的组件,下次渲染的时,直接使用对应的缓存。

import { memo } from "react";

const Child = memo(() => {
  console.log('Child被渲染')
  return ( 
    <div>
      <h1>Child</h1>
    
    </div>
  );
})

当我们的父组件的数据传递给子组件。这个时候对父组件的数据改变的时候子组件用来memo包裹但是子组件的数据也会更新。

memo 会对包裹的组件props进行了一个浅比较,如果props中的数据没有改变,则不会重新渲染对应的组件。

 如果我们传递一个函数呢?

如果传递的是一个函数或者其它引用值,哪怕引用值本身没有发生变化,但是由于父组件的重新渲染,导致对应的引用值被重新创建,得到一个新的堆内存地址。这就导致,我们传递引用值时,哪怕添加memo,也会导致子组件重新渲染

import { useState } from "react";

const Child = () => {
  console.log('Child被渲染')
  return ( 
    <div>
      <h1>Child</h1>

    </div>
  );
}


const Parent = () => {
  console.log("Parent被渲染")
  let [count, setCount] = useState(0)
  return (
    <div>
      <h1>Parent</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <hr />
     

useCallback

useCallback就可以解决我们对应的问题,这个hook会把函数进行缓存。

const Parent = () => {
  console.log("Parent被渲染")
  let [count, setCount] = useState(0)
  let [p2, setP2] = useState("可以改变,但是不去改变的p2")
  let p1 = "不变的参数p1"
  // let fn = () => {}
  let fn = useCallback(() => {}, [])
  
  return (
    <div>
      <h1>Parent</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <hr />
      <Child p1={p1} p2={p2} fn={fn}></Child>
    </div>
  );
}

 使用useCallback把函数包裹起来吗,不管我们的父组件如何被重新渲染,我们fn都还是那个函数,指向同一个推内存地址。因为memo时浅拷贝即只要堆内存地址没变就子组件也不会被重新渲染。

useCallback的第二个参数,是一个数组,当数组中的值发生变化时,useCallback就会被重新执行。让对应的fn发生改变。这个和useEffect的第二个参数一样的效果。

 

memo并不是必须配合useCallback使用的,useCallback也不是必须配合对应的memo使用,但是大部分情况,useCallback需要配合memo使用才能达到性能优化的效果。大部分情况,如果你直接使用过useCallback会负优化。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值