MST

星途 面试题库

面试题:TypeScript装饰器在React组件中的基础运用

请描述如何在一个简单的React函数式组件中,使用TypeScript装饰器来添加日志记录功能,即在组件每次渲染前打印一条日志信息。请给出具体的代码示例,并解释装饰器函数的参数和返回值的含义。
45.0万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
  1. 安装依赖: 首先确保项目安装了reactreact - domtypescript,如果要使用装饰器,还需要在tsconfig.json中开启experimentalDecoratorsemitDecoratorMetadata
    {
      "compilerOptions": {
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
      }
    }
    
  2. 代码示例
    import React from'react';
    
    // 装饰器函数
    function logBeforeRender(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
      const originalRender = descriptor.value;
      descriptor.value = function () {
        console.log('Component is about to render');
        return originalRender.apply(this, arguments);
      };
      return descriptor;
    }
    
    // React函数式组件
    class MyComponent extends React.Component {
      @logBeforeRender
      public render() {
        return <div>My Component</div>;
      }
    }
    
    export default MyComponent;
    
  3. 装饰器函数参数和返回值含义
    • 参数
      • target:对于类的方法装饰器,target是类的原型对象。在这个例子中,targetMyComponent.prototype
      • propertyKey:被装饰的属性(方法)的名称,这里是render
      • descriptor:包含被装饰方法的属性描述符,它有value(方法本身)、writableenumerableconfigurable等属性。
    • 返回值: 装饰器函数返回一个新的属性描述符(PropertyDescriptor),这个新的描述符会替换原来的描述符。在上述例子中,我们修改了descriptor.value(也就是render方法),在其执行前打印日志,然后返回修改后的descriptor,从而实现了在组件每次渲染前打印日志的功能。

需要注意的是,在React函数式组件中使用类的装饰器这种方式,MyComponent这里实际是基于类的组件写法。如果是纯粹的函数式组件,可以使用自定义的高阶组件(HOC)来实现类似功能,如下:

import React from'react';

// 高阶组件实现日志记录
function withLog(Component: React.FC) {
  return (props: React.PropsWithChildren) => {
    console.log('Component is about to render');
    return <Component {...props} />;
  };
}

// 函数式组件
const MyFunctionalComponent: React.FC = () => {
  return <div>My Functional Component</div>;
};

const LoggedComponent = withLog(MyFunctionalComponent);
export default LoggedComponent;

在这个高阶组件版本中,withLog函数接受一个组件Component作为参数,返回一个新的组件,新组件在渲染传入的Component之前打印日志。