非装饰器写法
下面这种链式调用写起来很麻烦,调用层级多的话,代码阅读性也会很差,ES7的装饰器语法可以解决这个问题
import React from 'react';
const CompOne = Comp => {
return props => {
return <Comp {...props} attrOne='comp1'></Comp>
}
}
const CompTwo = Comp => {
return props => {
return <Comp {...props} attrTwo='comp2'></Comp>
}
}
function App(props) {
return (
<div className="App">
<p>{props.attrOne}</p>
<p>{props.attrTwo}</p>
</div>
);
}
// 组件的链式调用
export default CompTwo(CompOne(App));
如何支持装饰器语法
-
安装依赖
yarn add customize-cra
如果Babel==6.x,安装
yarn add babel-plugin-transform-decorators-legacy -D
如果Babel>=7.x,安装
yarn add @babel/plugin-proposal-decorators -D
新项目都是7的版本,要是不放心,两个都装应该也行,但是本人没验证过
-
配置 config-overrides.js
配置好之后要重启,不然可能会报错
const { override, addBabelPlugins } = require('customize-cra'); module.exports = override( // 支持装饰器 addBabelPlugins( [ '@babel/plugin-proposal-decorators', { legacy: true } ] ) );
装饰器写法
装饰器语法只支持用class声明的组件,不支持函数式组件,如下图,使用报错
改写后:
import React, { Component } from 'react';
const CompOne = Comp => {
console.log('CompOne被调用了');
return props => {
return <Comp {...props} attrOne='comp1'></Comp>
}
}
const CompTwo = Comp => {
console.log('CompTwo被调用了');
return props => {
return <Comp {...props} attrTwo='comp2'></Comp>
}
}
// 多个装饰器自下而上执行
@CompTwo // 再执行这个
@CompOne // 先执行这个
class App extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<p>{this.props.attrOne}</p>
<p>{this.props.attrTwo}</p>
</div>
)
}
}
export default App;
Vscode中,使用装饰器会出现红线,这只是编辑器报错,不影响编译
解决方法:
Settings 中搜索 Experimental Decorators,勾选即可
浏览器打印结果