Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

基于Decorator的react组件扩展 #128

Open
BoyuZhou opened this issue Aug 30, 2016 · 0 comments
Open

基于Decorator的react组件扩展 #128

BoyuZhou opened this issue Aug 30, 2016 · 0 comments

Comments

@BoyuZhou
Copy link

基于Decorator的react组件扩展

react使用了ES2015语法之后,不支持mixin写法,但是可以通过decorator实现代码共享,使你的react程序变得更为可复用。

Decorator修饰器

修饰器(Decorator)是一个函数,用来修饰类的行为,在代码编译时,修改类的行为。
Decorator 可以通过返回特定的 descriptor 来”修饰” 类属性,也可以直接”修饰”一个类。即传入一个已有的类,通过 Decorator 函数”修饰”成了一个新的类。

function testable (target) {
target.isTestable = true;
}
@testable
class MyTestableClass {}

console.log(MyTestableClass.isTestable) //true

上面代码中@testable就是一个修饰器。它修改了MyTestableClass这个类的行为,为它加上了静态属性isTestable。

使用Decorator对react组件进行扩展

import React from 'react';
import withViewport from 'react-decorators/withViewport';

@withViewport
class MyComponent {
  render() {
    let { width, height } = this.props.viewport;
    return <div>Viewport: {width + 'x' + height}</div>;
  }
}

React.render(<MyComponent />, document.body);

withView 是一个类增强函数,或者类修饰器,传入一个被扩展组件(MyComponent),返回一个新的组件。新组建具有获取窗口尺寸变化的能力(viewport),并且将viewport 通过 this.props.viewport 传递给被扩展组件(MyComponent)。

高阶组件

高阶组件就是复用高阶函数的思想,为基础组件增加新功能。Higher-Order Component = Decorator + Components.

import React, { Component } from 'React';

const PopupContainer = (Wrapper) =>
  class WrapperComponent extends Component {
    componentDidMount() {
      console.log('HOC did mount')
    }

    componentWillUnmount() {
      console.log('HOC will unmount')
    }

    render() {
      return <Wrapper {...this.props} />;
    }
  }

这个例子就是一个高阶组件,传入一个组件,再返回一个新的组件。要想使用这个组件,可以这样做。

import React, { Component } from 'React';

@PopupContainer
class MyComponent extends Component {
  render() {}
}

export default MyComponent;

PopupContainer就是一个修饰器,传入基本组件MyComponent,返回一个新的组件。

当然如果有很多个高阶组件,可以使用compose来简化修饰器调用

import React, { Component } from 'React';
import R from 'ramda';

const Decorators = R.compose(Decorator3(param), Decorator2,Decorator1);

class MyComponent extends Decorators(Component) {}

参考文档:
react mixin前世今生
基于Decorator的组件扩展实践
Higher-order Components 高阶组件

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant