“createClass”语法是创建React组件的最初方法,但现在看来正在逐渐被“class”语法和无状态函数式组件所取代。如果您想要将一个组件从“createClass”升级到“class”,那么需要注意一些关键的区别。
初始状态与默认属性
使用“createClass”,您可以声明方法来返回给定组件的初始状态和默认属性。
React.createClass({
getInitialState() {
return { foo: 'bar' };
},
getDefaultProps() {
return { baz: 'qux' };
},
componentDidMount() {
console.log(
this.state,
this.props
);
}
});
两者都已经针对类语法进行了更改。相反,你需要在构造函数内分配初始状态。
class extends React.Component {
constructor() {
super();
this.state = { foo: 'bar' };
}
}
你需要将默认属性声明为静态属性。
class Qux extends React.Component {}
Qux.defaultProps = { baz: 'qux' };
混合
createClass
语法支持一种叫做混合的概念,它允许您提供其他代码来增强现有的生命周期方法。
const logOnMount = {
componentWillMount() {
console.log('Mounted!', new Date());
}
};
React.createClass({
mixins: [logOnMount]
});
任何使用
logOnMount
mixin的组件,每次挂载时都会将时间戳记录到控制台。
class
语法不支持混入(mixins),但您可以使用
高阶组件(higher-order components)来实现相同的功能。
function logOnMount(Component) {
return function(props) {
console.log('Mounted!', new Date());
return (
<Component {...props} />
);
}
}
自动绑定
createClass
语法提供了一些方便的自动绑定方法,这样您就可以安全地将组件方法作为回调传递,并不必担心this
上下文出现错误。
React.createClass({
bar() {
return true;
},
foo() {
this.bar();
},
render() {
return <button onClick={this.foo}>Click</button>;
}
});
onClick
处理程序将尝试使用触发的事件作为this
来调用this.foo
,但是由于this.foo
已经自动绑定了正确的上下文,所以不会出错。
以下是相同的示例,但使用类。
class extends React.Component {
bar() {
return true;
}
foo() {
this.bar();
}
render() {
return <button onClick={this.foo}>Click</button>;
}
}
foo
方法最终将this
设置为事件,该事件没有bar
属性。
为了解决这个问题,您需要在构造函数中显式地绑定方法,或者从箭头函数内部调用该方法。
constructor() {
this.foo = this.foo.bind(this);
}
render() {
return <button onClick={e => this.foo()}>Click</button>;
}