函数式的React

时间: 2019-05-08阅读: 174标签: react

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

原文:The functional side of React

作者:Andrea Chiarelli,译者:博轩  


链接: http://www.fly63.com/article/detial/3232

React中编写CSS的姿势

在任何环境之下其实没有最佳,最有最适合,那么在React中编写CSS也是类似的。在React中有很多编写CSS的方式,在社区中讨论最多的应该是CSS In JS 和 CSS Modules

react如何通过shouldComponentUpdate来减少重复渲染

在react开发中,经常会遇到组件重复渲染的问题,父组件一个state的变化,就会导致以该组件的所有子组件都重写render,尽管绝大多数子组件的props没有变化

react-redux 的使用

类似于 Vue,React 中组件之间的状态管理 第三方包为:react-redux。react-redux 其实是 Redux的官方React绑定库,它能够使你的React组件从Redux store中读取数据,并且向store分发actions以更新数据。

21 项优化 React App 性能的技术

在 React 内部,React 会使用几项巧妙的小技术,来优化计算更新 UI 时,所需要的最少的更新 DOM 的操作。在大多数情况下,即使你没有针对性能进行专项优化,React 依然很快,但是仍有一些方法可以加速 React 应用程序

React使用propTypes进行类型检查

注意: React.PropTypes 自 React v15.5 起已弃用。请使用 prop-types 库代替。随着你的应用的开发,你会使用类型检查的方法来捕获很多bug。对于一些应用,你可以使用js扩展就像Flow或者TypeScript去对整个应用进行类型检查

为什么说React 16是开发者的福音?

就像人们对更新移动应用程序和操作系统感到兴奋一样,开发人员也应该对更新框架感到兴奋。不同框架的新版本具有新特性和开箱即用的技巧。下面是将现有应用程序从 React 15 迁移到 React 16 时应该考虑的一些好特性。

React ref

React ref理解:通过指定ref获得你想操作的元素,然后进行修改.是当组件挂载后和卸载后,以及ref属性本身发生变化时,回调函数就会被调用。 因为ref引用的是组件的实例

react hook超实用的用法和技巧分析

react hook发布也已经有几个月了,相信有部分人已经开始使用了,还有些人在犹豫要不要用,可能更多人安于现状,没有要用的打算,甚至还有很多公司的react版本是15或以下的,迫于升级的难度没有使用。以我个人的观点,要不要使用react hook呢?

react中PureComponent浅对比策略

PureComponent实现了Component中没有实现的shouComponentUpdata()方法,会对state和props进行一次浅对比,本文介绍一下浅对比策略,源码中,实现浅对比的函数是:shallowEqual()

如何扩展 Create React App 的 Webpack 配置

Create React App(以下简称 CRA)是创建 React 应用的一个脚手架,它与其他脚手架不同的一个地方就是将一些复杂工具(比如 webpack)的配置封装了起来,让使用者不用关心这些工具的具体配置,从而降低了工具的使用难度。

fly63.com版权所有,内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权,请与小编联系!情况属实本人将予以删除!

广告赞助文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全