深入掌握reactjs和frintjs可观察组件实现

深入掌握reactjs和frintjs可观察组件实现_第1张图片
深入掌握reactjs和frintjs可观察组件实现
  • 引言
  • 高阶组件
  • 同步生成props
  • 可观察的Props
  • 访问父组件props
  • 使用helper函数生成props流
  • 编写默认props
  • 总结
  • 译者注

引言

本文主要专注使用frint-react包提供的observe高阶组件

尽管frint.js只是渲染库,同时支持ReactVue, 本文将会专注讨论React.js

为了帮助你理解这篇文章的大部分内容,建议阅读之前我们博客上的几篇文章

  • 使用React.js渲染Frint.js应用
  • 在React.js组件中如何访问Frint.js Provider组件

高阶组件

观察高阶组件的API十分简单:

import React from 'react';
import { observe } from 'frint-react';
function MyComponent(props) {
  return 
...
; } const ObservedComponent = observe(fn)(MyComponent); export default ObservedComponent;

observe接收函数fn, fn函数内部生成最终传递至目标组件的属性,然后返回接收组件为参数的函数实现观察功能

同步生成props

fn函数可以直接访问FrintJS应用实例:

const ObservedComponent = observe(function(app){
    // this will be the `props` in MyComponent
  return {};
})(MyComponent);

因为可以访问应用实例,就可以直接获取实例内部属性,包括: providers

const ObservedComponent = observe(function(app){
    return {
        appName: app.getName(),
        foo: app.get('foo')
    };
})(MyComponent);

MyComponent组件将会接收appNamefoo props属性

可观察的Props

observe高阶组件十分强大,可以直接將Rxjs 被观察对象作为流返回属性

想想随着时间变化的定时器:

import { interval } from 'rxjs/observable/interval';
const interval$ = interval(1000); // 每秒触发

可以把流转换下,转换成组件可以接受的属性兼容对象。

import { interval } from 'rxjs/observable/interval';
import { map } from 'rxjs/operators/map';
const interval$ = interval(1000);
const props$ = interval$.pipe(
  map(x => ({ interval: x }))
);

这里创建了一个新的props可观察对象,將interval映射为定时触发的{interval: 1}结构。

现在可以用observe连接组件

import { interval } from 'rxjs/observable/interval';
import { map } from 'rxjs/operators/map';
const ObservedComponent = observe(function (app) {
  const interval$ = interval(1000);
  return interval$.pipe(
    map(x => ({ interval: x }))
  );
})(MyComponent);

组件渲染时,MyComponent将会接收每秒增长的interval属性,触发重新渲染

访问父组件props

在返回可观察props之前,可能需要访问父组件的props属性

React中,从父组件传递下来的props属性随时都会变化。
正因为属性不断变化,observe高阶组件可以直接访问父组件props可观察对象:

const ObservedComponent = observe(function (app, props$) {
  // ...
})(MyComponent);

函数接收FrintJS实例参数和props$两个参数,props作为可观察对象从父组件传递下来。

使用helper函数生成props流

上面的例子已经很简单,只有一个可观察对象。随着应用功能增加,会有数倍的参数。
当你需要接收多个可观察对象,最后返回一个props流。

可以用frint-react中的streamProps辅助函数实现。

如果你是Rxjs大牛,可以忽略这部分

streamProps函数通过链式调用不断维持设置操作,设置完成所有值后,生成一个可观察对象

import { observe, streamProps } from 'frint-react';
const ObservedComponent = observe(function (app, props$) {
  return streamProps()
    // 同步数据
    .set('foo', 'foo value')
    .set({ bar: 'bar value' })
    // 来自其他可观察对象值
    .set(
      interval$, // rest of the arguments are mappers
      x => ({ interval: x })
    )
    .set(
      props$,
      parentProps => parentProps.somePropName,
      somePropName => ({ baz: somePropName })
    )
    // 生成一个props流
    .get$();
})(MyComponent);

上面的例子生成了一个props流,包括四个值:

  • foo, 值时foo value
  • bar, 值时bar value
  • interval, 值为持续增长的整形数字
  • baz 是从父组件传递的somePropName属性值

这些属性都可以在MyComponent中访问。

编写默认props

由于可观察对象是异步的,某些对象可能不会立即出发。
在新的props生成之前,需要传递默认值到目标组件中。

streamProps辅助函数接收一个可选参数,可以传递默认值:

import { streamProps } from 'frint-react';
const defaultProps = {
  foo: 'n/a',
  bar: 'n/a',
  baz: 'n/a',
};
const props$ = streamProps(defaultProps)
  .set(...)
  .get$();

所有属性初始值都是n/a, 一旦可观察对象执行完,props属性都会更新流到目标组件

总结

总得来说,observe高阶组件做了这几件事:

  • 包装目标组件,返回新被观察组件
  • 提供FrintJS应用实例访问
  • 提供父组件props属性观察对象访问
  • 允许通过同步或者异步Observable的方式生成目标组件可访问的新props属性

这种方式帮助和鼓励开发者尽可能编写无状态React组件,隔离任何业务逻辑,只处理props属性。

如果你又任何想法可以关注我们的Twitter

译者注

  • 原文链接

  • 因译者水平有限,如有错误,欢迎指正交流

你可能感兴趣的:(深入掌握reactjs和frintjs可观察组件实现)