2024金三银四react面试葵花宝典,欲练此功。。。

本文详述了React面试中的关键知识点,包括类组件与函数组件的生命周期、useMemo、React.memo、useCallback的区别、以及它们在性能优化中的应用。深入探讨了useEffect、useLayoutEffect和useInsertionEffect的执行机制,分析了为什么不应过度使用memoization。此外,还讨论了如何使用useRef、useReducer和useContext进行状态管理,以及React的diff算法与Vue的差异。最后,简要介绍了Redux的核心概念和工作流程。
摘要由CSDN通过智能技术生成

程序员的金三银四求职宝典

1.用类组件和函数组件分别编写react的不同 生命周期

在 React 中,类组件和函数组件的生命周期函数有所不同。以下是分别使用类组件和函数组件编写的挂载、更新和卸载阶段的生命周期函数示例:

类组件:

import React, {
    Component } from 'react';

class LifecycleComponent extends Component {
   
  constructor(props) {
   
    super(props);
    console.log('Constructor called');
  }

  componentDidMount() {
   
    console.log('Component did mount');
  }

  componentDidUpdate(prevProps, prevState) {
   
    console.log('Component did update');
  }

  componentWillUnmount() {
   
    console.log('Component will unmount');
  }

  render() {
   
    console.log('Render called');
    return (
      <div>
        Lifecycle Component
      </div>
    );
  }
}

export default LifecycleComponent;

函数组件:

import React, {
    useEffect } from 'react';

const FunctionComponent = () => {
   
  useEffect(() => {
   
    console.log('Component did mount');

    return () => {
   
      console.log('Component will unmount');
    };
  }, []);

  useEffect(() => {
   
    console.log('Component did update');
  });

  console.log('Render called');

  return (
    <div>
      Function Component
    </div>
  );
};

export default FunctionComponent;

在上面的示例中:

  • 类组件中的生命周期函数包括 constructorcomponentDidMountcomponentDidUpdatecomponentWillUnmount
  • 函数组件中使用 useEffect 钩子模拟了生命周期函数,第一个 useEffect 用于模拟 componentDidMountcomponentWillUnmount,第二个 useEffect 用于模拟 componentDidUpdate

无论是类组件还是函数组件,都能够实现 React 组件的生命周期功能。根据实际需求选择适合的编码方式。

2. useMemo,ReactMemo,useCallBack,三者的区别

在 React 中,useMemoReact.memouseCallback 是用于性能优化的钩子函数,它们的作用和用法略有不同。以下是它们的区别:

  1. useMemo

    • useMemo 用于在渲染过程中执行一些计算,并将计算结果进行缓存,只有当依赖项发生变化时才会重新计算。
    • 语法:const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    • useMemo 的第一个参数是一个函数,用于计算需要缓存的值,第二个参数是一个依赖数组,只有当依赖项发生变化时,才会重新计算值。
  2. React.memo

    • React.memo 是一个高阶组件,用于包裹函数组件,用于对组件进行浅比较的 PureComponent 的功能。
    • 当函数组件的 props 没有发生变化时,React.memo 将会使用之前的渲染结果,从而避免不必要的重新渲染。
    • 语法:const MemoizedComponent = React.memo(MyComponent);
    • React.memo 只接受一个参数,即需要进行性能优化的函数组件。
  3. useCallback

    • useCallback 用于缓存一个回调函数,并且只有在依赖项发生变化时才会重新创建这个回调函数。
    • 语法:const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]);
    • useCallback 的第一个参数是一个回调函数,第二个参数是一个依赖数组,只有当依赖项发生变化时,才会重新创建回调函数。

综上所述,useMemo​​和​​useCallback​​接收的参数都是一样,都是在其依赖项发生变化后才执行,都是返回缓存的值,区别在于​​useMemo​​返回的是函数运行的结果,​​useCallback​​返回的是函数。
useCallback(fn,deps)相当于 useMemo(()=> fn,deps) 。类似 shouldComponentUpdate, 判定该组件的 props 和 state 是否有变化,从而避免每次父组件render时都去重新渲染子组件
useCallback返回一个函数,当把它返回的这个函数作为子组件使用时,可以避免每次父组件更新时都重新渲染这个子组件,子组件一般配合 memo 使用

React.memo()useMemo() 的主要区别

从上面的例子中,我们可以看到 React.memo() 和 useMemo() 之间的主要区别:

React.memo() 是一个高阶组件,我们可以使用它来包装我们不想重新渲染的组件,除非其中的 props 发生变化
useMemo() 是一个 React Hook,我们可以使用它在组件中包装函数。 我们可以使用它来确保该函数中的值仅在其依赖项之一发生变化时才重新计算

虽然 memoization 似乎是一个可以随处使用的巧妙小技巧,但只有在绝对需要这些性能提升时才应该使用它。 Memoization 会占用运行它的机器上的内存空间,因此可能会导致意想不到的效果。

3.useEffectuseMemo 区别

useEffect是在DOM改变之后触发,useMemo在DOM渲染之前就触发
useMemo是在DOM更新前触发的,就像官方所说的,类比生命周期就是[shouldComponentUpdate]
useEffect可以帮助我们在DOM更新完成后执行某些副作用操作,如数据获取,设置订阅以及手动更改 React 组件中的 DOM 等
4.不要在这个useMemo函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo
5.在useMemo中使用setState你会发现会产生死循环,并且会有警告,因为useMemo是在渲染中进行的,你在其中操作DOM后,又会导致触发memo

4.问题:既然memo对性能优化有好处,为什么不把每个组件都包一下?

因为memo有缓存,大量使用,造成大量的性能开销。其次,props的比较只是浅比较,会有一些坑(解决浅比较的方式有:重新定义一个对象或者数组比如{…object,1},不用pop或者push)

useCallback 和 useMemo 仅仅在后续渲染(也就是重渲染)中起作用,在初始渲染中它们反而是有害的
useCallback 和 useMemo 作用于 props 并不能避免组件重渲染。只有当每一个 prop 都被缓存,且组件本身也被缓存的情况下,重渲染才能被避免。
只要有一丁点疏忽,那么你做的一切努力就打水漂了。所以说,简单点,把它们都删了吧。把包裹了“纯 js 操作“的 useMemo 也都删了吧。
与组件本身的渲染相比,它缓存数据带来的耗时减少是微不足道的,并且会在初始渲染时消耗额外的内存,造成可以被观察到的延迟。

5. useEffectuseLayoutEffectuseInsertionEffect分别用来干什么?

1.useEffect: 用于副作用捕获,在 dom 元素渲染之后调用,常用于页面数据处理工作。
2.useLayoutEffect: useEffect 的一个版本,在 DOM 更新之后同步执行,但在浏览器绘制之前执行,常用于页面元素布局工作,可能会阻塞页面渲染。
3.useInsertionEffect: useEffect 的一个版本,在 DOM 更新前执行。常用于 CSS-in-JS 插入动态样式。

6. useEffect 执行机制,写出下面代码运行的结果

import React, {
    useState } from "react";
import ReactDOM from "react-dom";

function App() {
   
  const [n, setN] = useState(0);
  const onClick = () => {
   
    setN(n + 1);
  };
  React.useEffect(() => {
   
    console.log("App");
    return () => {
   
      console.log("App挂了");
    };
  });
  return (
    <div className="App">
  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为了WLB努力

给点小钱,你的鼓励是我坚持动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值