需求:想让组件在挂载完成后打印输出当前组件名字。
作为一名ios开发者,依托oc强大的运行时,这个问题再简单不过了,但是js嘞?
最先想到的是替换组件Component.prototype原型链上的相关方法,但源码一看,发现componentDidMount不在组件的原型链方法之上,没法。
想起了es5中的mixins,大体实现如下:
const LogMixin = {
componentDidMount: function () {
console.log(this.componentName);
}
};
export const ComponentA = React.createClass({
mixins: [LogMixin],
componentName : 'ComponentA',
render: function () {
return <View/>
}
});
export const ComponentB = React.createClass({
mixins: [LogMixin],
componentName: 'ComponentB',
render: function () {
return <View/>
}
});
在组件ComponentA和ComponentB中添加上mixins属性,可以为当前组件扩展方法,且对生命周期方法并不会出现覆盖现象,扩展方法会先执行。系统的Touchable系列组件,如TouchableOpacity等使用了mixins作为组件方法扩展方式,值得学习。
mixins在es6中已经过期,官方提出的替代方案是高阶函数,实现如下
const Package = InnerComponent => class extends Component {
static propTypes = {
componentName: PropTypes.string.isRequired
};
componentDidMount() {
console.log(this.props.componentName);
}
render() {
return <InnerComponent {...this.props}/>;
}
};
class ComponentC extends Component {
render() {
return <View><Text>我是内容组件</Text></View>
}
}
export default Package(ComponentC)
Package是一个函数,参数InnerComponent是一个组件,返回值也是个继承自Component的组件,后面就是返回组件的实现方式。这个函数的作用就是对参数组件InnerComponent进行包装,扩充功能等。在这里,每次挂载目标组件ComponentC时,包装组件会先一步加载并调用componentDidMount方法打印出组件名字。
为了简化高阶函数的导出方式,增加代码可读性,可以采用es7提出的装饰器。非官方正式,而是babel提名,属于第三方。
首先安装:
npm install --save-dev babel-plugin-transform-decorators-legacy
再配置.babelrc文件
{
"presets": ["react-native"],
"plugins": [
"transform-decorators-legacy"
]
}
使用
@Package
export default class ComponentC extends Component {
render() {
return <View><Text>我是内容组件</Text></View>
}
}
@就是装饰器标识符,可以为组件、属性、方法等装饰另外的方法,这里Package作为一个方法装饰在组件ComponentC上面,效果跟上面完全一样。
网友评论