“在ReactJS中思考”如果我有AngularJS背景?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (96)

我熟悉在AngularJS中开发客户端应用程序,但现在我想开始使用ReactJS。

我还关注ReactNative,我认为这将彻底改变移动应用程序。

思考的方式以及React应用程序的结构与Angular的不同之处是什么?最大的区别是什么?

提问于
用户回答回答于

指令

如果熟悉Angular,那么想想React如何工作的方法是想象只使用Angular的指令。React没有任何控制器,服务,工厂或依赖注入的概念。如果只关注组件(以角度来说指令)。

这也是Angular以Angular 2为首的方式.Angular 2引入了一个称为组件的概念,并删除了指令,控制器和服务/工厂的概念。Angular 2仍然使用DI,但是你并没有将你的类绑定到Angular世界(你在Angular 1中做的)。

领域

所以Angular使用范围进行数据绑定,任何绑定到范围(或父范围)的模板都可以读取和打印该范围内的数据,甚至可以修改该范围。React中没有范围的概念,主要是因为React不像Angular那样进行脏检查,而且还因为React使用常规的JavaScript范围来确定视图可用的变量/对象。稍后更多。

模板

这是一个重要的区别。在Angular中,可以在不同的文件中定义模板,也可以将其定义为Javascript字符串。在React中,你可以在Javascript或JSX中定义你的视图。JSX是一种XML / HTML类似于Javascript的语言扩展,它允许描述HTML(或本机视图,如在React Native中)。

在JSX中,可以将元素的属性值设置为像<div className="myClass">或使用Javascript表达式的字符串,如下所示:<div className={myClassVariable}>其中,myClassVariable是一个常规的Javascript变量。JSX 之间{和之间的任何内容}都是普通的旧Javascript。你可以传递一个对象,一个函数,一个字符串等等。当你尝试在JSX中使用一个未定义的变量时,你的linter可以帮助你,这是在Angular模板中使用属性时你的linter不能做到的。

通过在JSX中定义视图而不是HTML字符串,您可以随时使用Javascript的全部功能。你不需要像Angular范围那样的东西,因为你已经有了一个Javascript范围,它决定了你可以在你的视图中使用什么。这就是为什么擅长Angular会让你擅长Angular,而擅长React的人也会让你成为更好的Javascript程序员。

数据绑定/突变/状态

Angular使用范围来定义应用程序状态。该范围可以从视图,控制器或指令中进行变异。范围相互继承,因此如果可以访问范围,还可以修改父范围。这是大型Angular应用程序难以管理的原因之一,因为应用程序的状态可以从很多地方改变。并且观察那些触发其他变化的变化使得它更难以掌握。

React使用道具和状态这两个概念。把它们想像为正规的Javascript函数。状态是在函数中定义的变量,而道具是传递给函数的参数。

函数中定义的变量可以在该函数中更改,并且可以将其作为参数传递给其他函数。

但传递给函数的参数不应在接收函数的函数中进行更改。他们可以创建一个局部变量并将其值赋给参数值并更改该局部变量。但它决不应该直接改变论据。

所以道具是从父组件传递给组件的值。接收道具的组件并不拥有它们,也不知道它们来自哪里,就像函数的参数一样。另一方面,状态由组件拥有,并且组件可以以任何想要的方式改变它,就像本地变量一样。

React知道组件的状态和道具何时发生变化,因为setState当想要更改组件的状态时必须显式调用它。它知道道具何时改变,因为当父组件呈现时你将道具传递给组件。

当状态改变时,React重新渲染组件(及其所有子组件)。请注意,它只会将它们重新渲染为组件的虚拟表示。然后它对自上次渲染以来发生变化的内容执行差异化,并且仅将实际更改应用于DOM。这实质上就是React的秘诀。编程模型是在每次发生事件时重新渲染所有内容,但只做最少量的工作。

我的控制器在哪里!?

就像我说的,React没有任何控制器的概念,它只关注组件。也就是说,当你使用React时,你经常仍然使用控制器/视图分离。你有组件(有时称为视图控制器)来处理数据获取和状态管理,但只做很少的渲染。相反,您有一个单独的组件,对数据获取和渲染有很多了解。因此,视图控制器组件知道如何获取数据,然后将数据传递给知道如何呈现数据的组件。一个简单的例子就是这样的:

var TodoItemsComponent = React.createClass({
  getInitialState: function () {
    return {
      todoItems: null
    }
  },
  componentDidMount: function () {
    var self = this;
    TodoStore.getAll().then(function (todoItems) {
      self.setState({todoItems: todoItems});
    });

    TodoStore.onChange(function (todoItems) {
      self.setState({todoItems: todoItems});
    });
  },
  render: function () {
    if (this.state.todoItems) {
      return <TodoListComponent todoItems={this.state.todoItems} />;
    } else {
      return <Spinner />;
    }
  }
});

var TodoListComponent = React.createClass({
  render: function () {
    return (
      <ul>
        {this.props.todoItems.map(function (todo) {
          return <li>{todo.text}</li>;
        })}
      </ul>
    );
  }
});

在这个例子中,有两个组件。一个只关心数据获取,另一个只关心渲染。他们都是React组件,但他们的职责非常不同。这是控制器和指令在Angular中的分离,但React不会强迫你进入它。

数据绑定

Angular使用数据绑定来保持视图与视图模型同步。React完全不使用数据绑定。可以说Angular监视视图模型的变化并相应地更新DOM,而React监视从组件返回的JSX以进行更改,并相应地更新DOM。

关注点分离

很多人对React持怀疑态度,因为他们觉得React没有以一种好的方式区分顾虑。而JSX往往是这一论点的目标。他们觉得在你的Javascript中加入标记是混淆了对视图和行为的担忧。如果你习惯了Angular,你可能不会同意在你的标记中描述行为是一个坏主意(因为你在Angular中也这么做)。一个经常被吹捧的反驳论点是,React“分离问题,而不是技术”,因为视图(标记)及其行为不是单独的问题,而是传统上独立的技术(HTML和Javascript)。通过共同定位行为和标记,会获得相当多的好处:

  1. 很容易看出是否有未使用的变量或函数。使用Angular,必须查看模板中的表达式,并搜索所有可以访问该范围的地方,以查看范围中是否存在未使用的变量或函数。
  2. 一个组件被隔离为一个文件,并且您不必在Javascript文件和模板文件之间来回切换。
  3. 对行为的改变通常需要改变标记,反之亦然。因此,将它保存在一个文件中可以更轻松地查看需要进行哪些更改。

这原来是一个文本墙,所以请让我知道,如果有什么我应该澄清或扩大。

用户回答回答于

ReactJS完全是关于(可重用的)组件,imo可以与Angular的指令进行比较。

所以我会说,想象一下在AngularJS中只用指令创建一个应用:)

几周前我开始在ReactJS中开发,起初很奇怪(在JS中编写模板代码,wtf?),但现在我已经习惯了。我最近也开始玩React-Native,这真棒!

我现在可以在这里列出Angular和React之间的很多不同之处,但是其他人已经写了一些很好的文章,所以我建议您阅读这些文章以获得更清晰的想法。

然后还有很棒的反应,一个反应库,资源,教程,文章的汇编

与问题相关,本节可能是最感兴趣的部分:

更多关于ReactJS方法的文章以及与其他框架的比较

扫码关注云+社区

领取腾讯云代金券