This article mainly introduces the three ways to create components in React and their differences. It has certain reference value. Let’s take a look at them together.
After React was launched, three definitions appeared for different reasons. The method of react component has the same goal in different ways; three specific methods:
Functionally defined stateless component
es5 native method React.createClass Defined components
es6 form extends React.ComponentDefined components
Although there are three ways to define react components, then these three What is the difference between these two ways of defining components? In other words, why do corresponding definitions appear? Let’s briefly introduce it below.
Stateless functional components
The creation of stateless functional components has appeared since React version 0.14. It is used to create pure display components, which are only responsible for display based on the incoming props and do not involve state operations. Specific stateless functional components, the official pointed out:
In most React codes, most components are written as stateless components, which can be built into other components through simple combination; this is done through multiple A design pattern that is simple and then merged into a large application is advocated.
The stateless functional component is formally represented as a component class with only one render method. It is created in the form of a function or ES6 arrow function, and the component is stateless. The specific creation form is as follows:
function HelloComponent(props, /* context */) { return <p>Hello {props.name}</p> } ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode)
The creation form of stateless components makes the code more readable, and reduces a lot of redundant code and streamlines it. There is only one render method, which greatly enhances the convenience of writing a component. In addition, stateless components have the following notable features:
1. The component will not be instantiated. The overall rendering performance has been improved
Because the component is simplified into a function of the render method. Since it is a stateless component, the stateless component will not be in the process of component instantiation. The instantiation process does not need to allocate excess memory, so the performance is improved to a certain extent.
2. Components cannot access the this object
Since there is no instantiation process, stateless components cannot access the objects in the component this, such as: this.ref, this .state, etc. cannot be accessed. If you want to access, you cannot use this form to create components
3. Components cannot access life cycle methods
Because stateless components do not require component life cycle management and state management, so when the underlying implementation of this form of component does not implement the component's life cycle method. Therefore, stateless components cannot participate in the various life cycle management of components.
4. Stateless components can only access input props. The same props will get the same rendering results without side effects.
Stateless components are encouraged to In large projects, try to use simple writing methods to divide the originally huge components. In the future, React will also perform a series of optimizations for stateless components, such as meaningless checks and memory allocation, so as long as there are If possible, try to use stateless components.
React.createClass
`React.createClass` is the first recommended way to create components in react. This is a React component implemented in ES5's native JavaScript. Its form is as follows:
var InputControlES5 = React.createClass({ propTypes: {//定义传入props中的属性各种类型 initialValue: React.PropTypes.string }, defaultProps: { //组件默认的props对象 initialValue: '' }, // 设置 initial state getInitialState: function() {//组件相关的状态对象 return { text: this.props.initialValue || 'placeholder' }; }, handleChange: function(event) { this.setState({ //this represents react component instance text: event.target.value }); }, render: function() { return ( <p> Type something: <input onChange={this.handleChange} value={this.state.text} /> </p> ); } }); InputControlES6.propTypes = { initialValue: React.PropTypes.string }; InputControlES6.defaultProps = { initialValue: '' };
Compared with stateless components, React.createClass and React.Component to be described later both create stateful components. These Components are instantiated and have access to the component's lifecycle methods. However, with the development of React, problems with the React.createClass form itself have been exposed:
React.createClass will self-bind function methods (unlike React.Component which only binds the things you need to care about) function) results in unnecessary performance overhead and increases the likelihood of code becoming obsolete.
The mixins of React.createClass are not natural and intuitive enough; the React.Component form is very suitable for higher-order components (Higher Order Components--HOC), which displays the mixins in a more intuitive form More powerful functions, and HOC is pure JavaScript, no need to worry about them being abandoned.
React.Component
React.Component is used to create react components in the form of ES6. It is currently highly recommended for React to create components. The state component approach will eventually replace the React.createClass form; compared to React.createClass, code reuse can be better achieved. Change the above form of React.createClass to React.Component as follows:
class InputControlES6 extends React.Component { constructor(props) { super(props); // 设置 initial state this.state = { text: props.initialValue || 'placeholder' }; // ES6 类中函数必须手动绑定 this.handleChange = this.handleChange.bind(this); } handleChange(event) { this.setState({ text: event.target.value }); } render() { return ( <p> Type something: <input onChange={this.handleChange} value={this.state.text} /> </p> ); } } InputControlES6.propTypes = { initialValue: React.PropTypes.string }; InputControlES6.defaultProps = { initialValue: '' };
The difference between React.createClass and React.Component
In addition to the different grammatical formats of defining components in the code shown above, there are many important differences between the two. The main differences between the two are described below.
Function this self-binding
In the component created by React.createClass, the this of each member function is automatically bound by React. Any time you use it, just use this.method directly, and this in the function will be set correctly.
const Contacts = React.createClass({ handleClick() { console.log(this); // React Component instance }, render() { return ( <p onClick={this.handleClick}></p> ); } });
React.Component创建的组件,其成员函数不会自动绑定this,需要开发者手动绑定,否则this不能获取当前组件实例对象。
class Contacts extends React.Component { constructor(props) { super(props); } handleClick() { console.log(this); // null } render() { return ( <p onClick={this.handleClick}></p> ); }
当然,React.Component有三种手动绑定方法:可以在构造函数中完成绑定,也可以在调用时使用method.bind(this)来完成绑定,还可以使用arrow function来绑定。拿上例的handleClick函数来说,其绑定可以有:
constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); //构造函数中绑定 }
<p onClick={this.handleClick.bind(this)}></p> //使用bind来绑定 <p onClick={()=>this.handleClick()}></p> //使用arrow function来绑定
组件属性类型propTypes及其默认props属性defaultProps配置不同
React.createClass在创建组件时,有关组件props的属性类型及组件默认的属性会作为组件实例的属性来配置,其中defaultProps是使用getDefaultProps的方法来获取默认组件属性的
const TodoItem = React.createClass({ propTypes: { // as an object name: React.PropTypes.string }, getDefaultProps(){ // return a object return { name: '' } } render(){ return <p></p> } })
React.Component在创建组件时配置这两个对应信息时,他们是作为组件类的属性,不是组件实例的属性,也就是所谓的类的静态属性来配置的。对应上面配置如下:
class TodoItem extends React.Component { static propTypes = {//类的静态属性 name: React.PropTypes.string }; static defaultProps = {//类的静态属性 name: '' }; ... }
组件初始状态state的配置不同
React.createClass创建的组件,其状态state是通过getInitialState方法来配置组件相关的状态;
React.Component创建的组件,其状态state是在constructor中像初始化组件属性一样声明的。
const TodoItem = React.createClass({ // return an object getInitialState(){ return { isEditing: false } } render(){ return <p></p> } })
class TodoItem extends React.Component{ constructor(props){ super(props); this.state = { // define this.state in constructor isEditing: false } } render(){ return <p></p> } }
Mixins的支持不同
Mixins(混入)是面向对象编程OOP的一种实现,其作用是为了复用共有的代码,将共有的代码通过抽取为一个对象,然后通过Mixins进该对象来达到代码复用。
React.createClass在创建组件时可以使用mixins属性,以数组的形式来混合类的集合。
var SomeMixin = { doSomething() { } }; const Contacts = React.createClass({ mixins: [SomeMixin], handleClick() { this.doSomething(); // use mixin }, render() { return ( <p onClick={this.handleClick}></p> ); } });
但是遗憾的是React.Component这种形式并不支持Mixins,至今React团队还没有给出一个该形式下的官方解决方案;但是React开发者社区提供一个全新的方式来取代Mixins,那就是Higher-Order Components。
如何选择哪种方式创建组件
由于React团队已经声明React.createClass最终会被React.Component的类形式所取代。但是在找到Mixins替代方案之前是不会废弃掉React.createClass形式。所以:
能用React.Component创建的组件的就尽量不用React.createClass形式创建组件。
除此之外,创建组件的形式选择还应该根据下面来决定:
1、只要有可能,尽量使用无状态组件创建形式。
2、否则(如需要state、生命周期方法、ref等),使用`React.Component`这种es6形式创建组件
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
The above is the detailed content of About three ways to create components in React and their differences. For more information, please follow other related articles on the PHP Chinese website!