DAY6 摸鱼日记

本文详细介绍了React中的Ref、forwardRef、useImperativeHandle、useMemo和useCallback的用法,以及它们在性能优化中的作用,特别是如何通过这些工具控制DOM操作和避免不必要的组件渲染。
摘要由CSDN通过智能技术生成

学习Ref,forwardRef,useImperativeHandle

React.forwardRef会创建一个React组件,这个组件能够将其接受的ref属性转发到其组件树下的另一个组件中;用于父组件操作子组件的DOM,也可以理解为子组件向父组件暴露 DOM 引用。
ref属性是React的特殊属性,不能直接使用。
ref不能作为prop传递
如果想传递ref,需要借助forwardRef函数
常用情况:
(1)转发refs到DOM组件
(2)在高阶组件种转发refs

实例:在这里插入图片描述

要实现父组件点击按钮,光标定位到子组件的输入框种,需要使用forwardRef,
在这里插入图片描述
useImperativeHandle(ref, createHandle, [deps]),可以在使用ref时自定义暴露给父组件的实例值,减少暴露给父组件的属性,如以下只暴露focus方法,避免父组件操作整个input元素。
在这里插入图片描述

useMemo,useCallback和memo

useMemo是一个用于性能优化的hook,避免在组件重新渲染时执行昂贵的计算;接受两个参数,一个函数和一个以来数字。当依赖数组种的值发生变化时,useMemo会重新计算并返回新的值,否则将返回上一次计算的值。

import React, { useMemo } from 'react';

const a = 1, b = 4;
function App() {
  const result = useMemo(() => {
    console.log(" calculation..." + a + "*" + b);
    return a * b;
  }, [a, b]);
  return <div>Result: {result}</div>;
}

export default App;

ExpensiveComponent 接受两个属性 a 和 b 并使用 useMemo 钩子来计算 a 和 b 的乘积。当 a 或 b 发生变化时,useMemo 会重新计算结果。否则,它将返回上一次计算的值,避免了不必要的计算。

useCallback 也是用于优化性能的hook,帮助我们避免在组件重新渲染时创建新的函数实例。接受两个参数:一个函数和一个依赖数组。当依赖数组中的值发生变化时,useCallback会返回一个新的函数实例,否则则返回上一次创建的函数实例。

import React, { useCallback } from "react";

function ButtonComponent({ onClick, children }) {
  return <button onClick={onClick}>{children}</button>;
}

function ParentComponent() {
  const handleClick = useCallback(() => {
    console.log("Button clicked");
  }, []);

  return (
    <div>
      <ButtonComponent onClick={handleClick}>Click me</ButtonComponent>
    </div>
  );
}

ButtonComponent 的组件,接受一个 onClick 函数属性。 ParentComponent使用 useCallback 钩子来创建一个 handleClick 函数。当 ParentComponent 重新渲染时,useCallback 会返回上一次创建的 handleClick 函数实例,避免了不必要的函数创建。
在这里插入图片描述

import React, { useCallback, memo } from 'react';

type ChildComponentProps = {
  handleClick: () => void;
}
const ParentComponent = () => {
  const handleClick = useCallback(() => {
    console.log('Button clicked');
  }, []); // 回调函数不依赖于任何值,因此只在组件首次渲染时创建
  return <ChildComponent handleClick={handleClick} />;
};

const ChildComponent =  React.memo<ChildComponentProps>(({ handleClick }) => {
  console.log('ChildComponent rendered');
  return <button onClick={handleClick}>Click me</button>;
});

function App() {
  return <ParentComponent />;
}

export default App;

memo是用于性能优化的高阶函数,避免在父组件重新渲染时重新渲染子组件。memo 接受一个组件作为参数,并返回一个新的组件。当新组件的属性发生变化时,它会重新渲染。否则,它将跳过渲染并返回上一次渲染的结果。

=> 我导说不对应该是这么说:memo 用于接收一个函数组件并将缓存后的组件返回,该组件的 props 未发生变化时组件不会重新执行

import React, { memo } from "react";

const ChildComponent = memo(function ChildComponent({ text }) {
 console.log("ChildComponent rendered");
 return <div>{text}</div>;
});

function ParentComponent({ showChild }) {
 return (
   <div>
     {showChild && <ChildComponent text="Hello, world!" />}
     <button onClick={() => setShowChild(!showChild)}>Toggle child</button>
   </div>
 );
}

ChildComponent 使用 memo 高阶组件对其进行了优化。 ParentComponent 可以切换 ChildComponent 的显示。当 ParentComponent 重新渲染时,ChildComponent 的属性没有发生变化,因此它不会重新渲染。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值