【译】函数式的React

栏目: 服务器 · 发布时间: 4年前

内容简介:原文:作者:Andrea Chiarelli译者:博轩

原文: The functional side of React

作者:Andrea Chiarelli

译者:博轩

React是现在最流行的 JavaScript 库之一。使用 React 可以非常轻松地创建 Web 用户交互界面。 它的成功有很多因素,但也许其中一个因素是清晰有效的编程方法。

React 的世界中, UI 是由一个一个组件所组成的。组件可以组合在一起以创建其他组件, 应用本身就是一个包含了所有组件的一个大组件。开发者使用 React 会很容易联想到: 面向对象编程 。因为定义组件的语法本身,就会给人这种感觉:

class HelloReact extends Component {
  render() {
    return (<div>Hello React!</div>);
  }
}

然鹅,在面向对象的的表象之下, React 隐藏了一种函数式的特质。让我们看看这些特质都是什么?

使用 render() 渲染输出

React组件的一大特征是是包含了 render() 方法。没有包含 render() 方法的组件不是 React 组件。 render() 方法总会返回一个 React 元素,这种行为就像是组件的一种特征一样。换句话说, React 会要求任何组件必须有输出。组件是根据输入来返回输出的,这样来考虑组件的话,就会让你感觉组件更像一个函数,而不是一个对象。

组件就是一个函数

实际上,您不仅可以将 React 组件视为函数。 您还可以用函数来实现组件。 以下代码展示了如何使用函数实现上面定义的组件:

const HelloReact = () => <div>Hello React!</div>;

如您所见,它是一种实现组件的简单而紧凑的方法。

此外,您可以将参数传递给函数:

const Hello = (props) => <div>Hello {props.name}!</div>;

在上面的示例中,您传递了 props 参数,这里的 props 对象用于将数据从一个组件传递到另一个组件。

props 的不变性

如你所知, props 是不可改变的,你可以阅读他们,但你无法改变它们。这也正是 React 组件的函数特性之一。 props 是组件的输入参数,因此给予其不可变性可以避免副作用。实际上,这也是函数式编程的基本原则之一:函数不能更改输入参数。

译注:纯函数的介绍,推荐看下这个 - 函数式编程 - wiki ,以及我之前翻译过的 【译】JavaScript 中的函数式编程原理

单项数据流

关于 React ,它的另一个特性就是 单项数据流 。这意味着在组件的层次结构中,数据必须从较高的组件流向较低的组件,反之亦然。如果我们将组件视为对象,这个观点就会显得有些牵强。相反,如果我们从函数的角度去考虑组件,就会显得很自然。

考虑一下下面的代码:

class App extends Component {
  render() {
    return (<Hello name="React" />)
  };
}

class Hello extends Component {
  render() {
    return (<div>Hello {props.name}!</div>);
  }
}

例子中有两个组件: App 组件使用 Hello 组件来展示 “Hello React!” 。同时,例子中也 隐式 的定义了组件之间的层次结构。但是乍一看,无法通过 name 属性来来看清楚数据的流向。

现在,让我们来看看使用函数修改之后的代码:

const App = () => <Hello name="React" />;
const Hello = (props) => <div>Hello {props.name}!</div>;

通过上面组件的层级结构可以清楚的看出,不过是 App()Hello() ,两个函数的组合。你也可以将其视为下面的内容:

const App = () => Hello("React");

从上面的例子中就可以很明显的看出, “React” 文本是怎样在 App 组件中传递的了。

译注:这里原文例子中使用的是 const App = () => Hello("John"); ,和文章中的 "React" 不相符,所以我改了例子中传递的文案,嘿嘿嘿...

组合 vs 继承

在面向对象的编程范例中,对于类,很容易将继承视为一种标准。 但是,如果从函数的角度考虑 React 组件,继承就会显得不那么自然。

例如,假设您要升级 Hello 组件,以便它还可以显示 “欢迎消息” 。 您可以将其与 Hello 组件组合来创建新组件,比如下面的例子:

const HelloAndWelcome = (props) => <div><Hello {…props} /><p>Welcome to React!</p></div>;

正如 Facebook团队 所宣称的那样 ,真的很少需要继承。

高阶组件和高阶函数

高阶组件是 React 编程中的常见模式。 它允许重用组件逻辑来创建新组件。 简单来说,高阶组件是一个函数,它将一个组件作为输入并返回一个新组件作为其输出。 以下是高阶组件的示例:

const AddWelcome = (GreetingComponent) => {
  class TheNewComponent extends Component {
    render() {
      return (
        <div>
          <GreetingComponent {…this.props}/>
          <p>Welcome to React!</p>
        </div>);
      }
    }

  return TheNewComponent;
};

函数 AddWelcome() 接受 GreetingComponent 参数,并在新组件 TheNewComponent 定义的 render() 方法中使用它。 这个新组件只是在 GreetingComponent 的输出后添加一条欢迎消息。 最后,函数 AddWelcome() 会返回新组件。

您可以使用此功能,如以下示例所示:

const HelloAndWelcome = AddWelcome(Hello);

通过使用 AddWelcome() 包装 Hello 组件,您将获得一个新组件。

您可以将上面例子中的高阶函数 AddWelcome() 用函数的方式来重新整理:

const AddWelcome = (GreetingComponent) => {
  const TheNewComponent = (props) => <div><GreetingComponent {…props}/><p>Welcome to React!</p></div>;
  
  return TheNewComponent;
};

如你所见,这就像是一个 高阶函数 ,这个函数接受一个函数,返回一个新的 React 元素。

组件和状态

应用程序的状态是随时间变化的数据集。 函数式编程范例旨在避免在应用程序中使用状态。 实际上,应用程序状态管理是软件开发中复杂性的主要来源之一。 但是,由于你不能没有它,至少你应该尝试限制它的使用并使其更易于管理。

React 的开发指南促进了无状态组件的创建,即无 state 组件。 这种组件的输出仅仅取决于传入的 props 。 无状态组件看起来很像纯函数,实际上也是如此。

但是,如您所知,在不使用 state 的情况下无法编写复杂的应用程序。 诀窍是在应用程序的几个点上隔离 state ,如果在一个点上更好。 此策略会要求开发人员在根组件中使用 状态提升 。 换句话说,应该在上层节点中保留状态,而其后代应该是无状态组件。 这样,我们可以更好地控制状态,因为它只由单个根组件管理。

结论

对于刚开始使用 React 的开发者来说, React 并不是像看起来那样,它更加适合函数式编码的原则,而不是面向对象的原则。通常,这允许开发者编写更加正式可验证的代码,例如使用自动化测试来测试应用程序。 我建议充分利用 React 的函数特性来编写更易于维护的代码。

Andrea Chiarelli 是 Beginning React

的作者。

本文已经联系原文作者,并授权翻译,转载请保留原文链接


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Machine Learning in Action

Machine Learning in Action

Peter Harrington / Manning Publications / 2012-4-19 / GBP 29.99

It's been said that data is the new "dirt"—the raw material from which and on which you build the structures of the modern world. And like dirt, data can seem like a limitless, undifferentiated mass. ......一起来看看 《Machine Learning in Action》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试