MST

星途 面试题库

面试题:Angular和React在组件化架构设计上的关键不同

Angular和React都采用了组件化架构,从组件的创建、通信、生命周期管理等方面,详细说明它们在组件化架构设计上的关键不同之处,以及这些不同对应用开发和维护的影响。
22.2万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

组件创建

  • Angular
    • 使用TypeScript类来定义组件,通过装饰器@Component来标记一个类为组件,并配置元数据,如选择器、模板、样式等。例如:
import { Component } from '@angular/core';

@Component({
  selector: 'app - my - component',
  templateUrl: './my - component.html',
  styleUrls: ['./my - component.css']
})
export class MyComponent {
  // 组件逻辑
}
  • 模板使用Angular自己的模板语法,支持双向数据绑定、指令等。
  • React
    • 既可以使用ES6类来定义组件,也可以使用函数式组件(从React 16.8起,函数式组件可以使用Hook来管理状态和生命周期)。
    • 类组件示例:
import React, { Component } from'react';

class MyComponent extends Component {
  render() {
    return <div>My React Component</div>;
  }
}
  • 函数式组件示例:
import React from'react';

const MyComponent = () => {
  return <div>My React Component</div>;
};
  • 模板使用JSX语法,将HTML和JavaScript融合在一起,更强调JavaScript的逻辑性。

组件通信

  • Angular
    • 父子组件通信:父组件通过属性绑定将数据传递给子组件;子组件通过@Output()装饰器和EventEmitter来发射事件给父组件。例如:
      • 父组件模板:<app - child - component [inputData]="parentData" (childEvent)="handleChildEvent($event)"></app - child - component>
      • 子组件:
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app - child - component',
  templateUrl: './child - component.html'
})
export class ChildComponent {
  @Input() inputData;
  @Output() childEvent = new EventEmitter();

  onButtonClick() {
    this.childEvent.emit('Some data from child');
  }
}
  • 非父子组件通信:可以通过服务(Service)来共享数据,服务是单例的,在整个应用中都可以访问。
  • React
    • 父子组件通信:父组件通过属性(props)将数据传递给子组件,子组件不能直接修改props。要向父组件传递数据,子组件需要将父组件传递过来的回调函数作为props,在需要时调用该回调函数并传递数据。例如:
      • 父组件:<ChildComponent data={parentData} handleChildData={this.handleChildData.bind(this)} />
      • 子组件:
import React from'react';

const ChildComponent = (props) => {
  const handleClick = () => {
    props.handleChildData('Some data from child');
  };

  return <button onClick={handleClick}>Send data to parent</button>;
};
  • 非父子组件通信:可以使用Context(从React 16.3起有了更完善的API)来共享数据,但官方建议尽量避免过度使用Context,因为它会使组件之间的关系变得复杂。也可以使用第三方状态管理库如Redux、MobX等。

生命周期管理

  • Angular
    • 组件生命周期钩子:有多个生命周期钩子函数,如ngOnInit(组件初始化后调用)、ngOnChanges(当组件的输入属性发生变化时调用)、ngOnDestroy(组件销毁前调用)等。例如:
import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app - my - component',
  templateUrl: './my - component.html'
})
export class MyComponent implements OnInit, OnDestroy {
  ngOnInit() {
    // 初始化逻辑
  }

  ngOnDestroy() {
    // 清理逻辑,如取消订阅等
  }
}
  • React
    • 类组件生命周期:有componentDidMount(组件挂载后调用)、componentDidUpdate(组件更新后调用)、componentWillUnmount(组件卸载前调用)等。例如:
import React, { Component } from'react';

class MyComponent extends Component {
  componentDidMount() {
    // 初始化逻辑
  }

  componentDidUpdate(prevProps, prevState) {
    // 更新逻辑
  }

  componentWillUnmount() {
    // 清理逻辑,如取消订阅等
  }

  render() {
    return <div>My React Component</div>;
  }
}
  • 函数式组件与Hook:使用useEffect Hook来模拟生命周期效果。useEffect在组件挂载和更新后都会执行,通过传入依赖数组可以控制其执行时机。例如:
import React, { useEffect } from'react';

const MyComponent = () => {
  useEffect(() => {
    // 类似 componentDidMount 和 componentDidUpdate 的逻辑
    return () => {
      // 类似 componentWillUnmount 的清理逻辑
    };
  }, []); // 空数组表示只在挂载时执行一次

  return <div>My React Component</div>;
};

对应用开发和维护的影响

  • 开发体验
    • Angular:学习曲线较陡,因为其基于TypeScript,有较多的概念如模块、依赖注入、装饰器等。但一旦掌握,代码结构清晰,适合大型企业级应用开发,其双向数据绑定在某些场景下可以减少代码量。
    • React:相对容易上手,特别是对于熟悉JavaScript的开发者。JSX语法灵活,函数式编程风格使得代码更简洁,适合快速迭代的项目,但其单向数据流要求开发者更仔细地管理数据传递。
  • 维护性
    • Angular:由于其严格的类型系统和结构化的架构,代码在维护时更容易理解和修改,特别是在大型团队中。但如果项目架构设计不合理,修改起来可能会比较复杂。
    • React:代码相对灵活,但在大型应用中,如果组件通信和状态管理没有设计好,可能会导致代码难以维护。不过,使用状态管理库可以一定程度上解决这个问题。