【译】函数式的React

原文:
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 的作者。

本文已联络原文作者,并受权翻译,转载请保存原文链接

    原文作者:joking_zhang
    原文地址: https://segmentfault.com/a/1190000019095817
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞