React中创建组件的方式
特别声明:为感谢社区广大朋友对小站的支持,自2019年10月1日至2019年11月11日开通年费VIP通道,年费价格为 ¥299.00元。如果您喜欢小站的内容,可以点击开通会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!(^_^)
学习React也有一段时间了,虽然天天都在围绕着组件打转转,但在React中怎么构建组件呢并没有去深入的了解。事实上呢?在React中的组件还是有些复杂的,从概念上来说就不简单。比如说,类组件,函数组件,无状态组件和高阶组件等。另外创建组件的方式也有所不同,比如最早使用React.createClass
来创建组件,有了ES6之后使用extends React.Component
(借助ES6的class
特性)创建组件,而今天又流行使用函数(Hooks)方式来创建组件。那么他们之间如何创建组件,又有何区别呢?在这篇文章中我们就先来学习和探讨在React中如何创建组件。
先来看React.createClass
如何创建组件?
React.createClass
如果你一直以来都在使用React的话,那么对React.createClass
这个API并不陌生。在React中,最初就是用这个API来创建React组件。将描述组件的所有信息都将作为对象传递给createClass
。
createClass
方法为开发人员提供了一个工厂方法(Factory Method),可以在不使用JavaScript 类的情况下创建React类组件。这是在ES之前创建React组件方法之一,因为在ES5中没有可用的类语法:
const App = React.createClass({
getInitialState: function() {
return {
value: '大漠'
}
}
onChange: function(e) {
this.setState({
value: e.target.value
})
}
render: function() {
return (
<div className="card">
<h1>使用 React.createClass 创建组件</h1>
<input
value={this.state.value}
type="text"
onChange={this.onChange}
/>
<p>Hello, {this.state.value} (^_^)!</p>
</div>
)
}
})
const rootElement = document.getElementById("app");
ReactDOM.render(<App />, rootElement);
上面的Demo在React V15.5版本上运行。
createClass()
方法接受一个对象,该对象为React组件定义方法。getInitialState()
函数用于为React组件设置初始状态,强制使用render()
方法在JSX中用于输出;额外的方法(比如onChange
)是通过向对象传递更多的函数而添加的。
React中的生命周期也是可用的。例如,为了每次将值从input
中输入存到浏览器的本地存储中(localStorage
),我们可以使用componentDidUpdate()
生命周期,该方法是将一个函数传递给对象,对象键以React的生命周期方法命名。此外,当组件接收到初始状态时,可以从本地存储中读取该值:
const App = React.createClass({
getInitialState: function() {
return {
value: localStorage.getItem('userName') || '@大漠'
}
},
componentDidUpdate: function(){
localStorage.setItem('userName', this.state.value)
},
onChange: function(e) {
this.setState({
value: e.target.value
})
},
render: function() {
return (
<div className="card">
<h1>使用React.createClass创建组件</h1>
<input
type="text"
value={this.state.value}
onChange={this.onChange}
/>
<p>Hello, {this.state.value} (^_^)!</p>
</div>
)
}
})
const rootElement = document.getElementById("app");
ReactDOM.render(<App />, rootElement);
这个示例具有本地存储的功能,每当重新加载或刷新浏览器时,当组件第一次挂载时,应该会显示之前在input
中输入的本地存储的初始状态。
注意:React核心包中不再提供
React.createClass()
方法。如果你想尝试它,必须安装一个额外的包:npm i create-react-class
。时至今日,应该尽可能地避免使用它。在这里可以获取到React.createClass()
创建组件更多的信息。
React Mixins
React中引入了React Mixins,作为React的第一个可重用组件逻辑,这是一种高级模式。使用Mixin,可以将React组件的逻辑提取出来成为一个独立对象。当在组件中使用Mixin时,所有来自Mixin的特性都被引入组件:
var localStorageMixin = {
getInitialState: function(){
return {
value: localStorage.getItem('userName') || '@大漠'
}
},
setLocalStorage: function(val) {
localStorage.setItem('userName', val)
}
}
var App = React.createClass({
mixins: [localStorageMixin],
componentDidUpdate: function(){
this.setLocalStorage(this.state.value)
},
onChange: function(e) {
this.setState({
value: e.target.value
})
},
render() {
return (
<div className="card">
<h1>使用React Mixin和createClass创建组件</h1>
<input
type="text"
value={this.state.value}
onChange={this.onChange}
/>
<p>Hello, {this.state.value} (^_^)!!!</p>
</div>
)
}
})
const rootElement = document.getElementById("app");
ReactDOM.render(<App />, rootElement);
本例中,Mixin提供从本地存储中读取组件的初始状态,并使用setLocalStorage()
方法扩展组件,该方法稍后将在实际组件中使用。为了使用Mixin更加灵活,我们可以使用一个函数来返回一个对象:
function getLocalStorageMixin(localStorageKey) {
return {
getInitialState: function(){
return {
value: localStoragee.getItem(localStorageKey) || ''
}
},
setLocalStorage: function(value) {
localStorage.setItem(localStorageKey, value)
}
}
}
var App = React.createClass({
mixins: [getLocalStorageMixin('userName')],
// ...
})
注意:现在在React中不再使用Mixins了,因为它们有几个缺点。有关于React Mixins更多的信息,可以点击这里进行了解。
createClass()
是创建React组件的一种简单而有效的方法。React最初使用createClass
API的原因是,当时JavaScript没有内置的class
。当然,这种情况最终改变了。ES6开始引入了class
这个关键字,也可以使用类来创建组件。这让React进入了一个两难的境地,要么继续使用createClass
,要么跟进ES6,使用class
来创建组件。事实证明,React选择了后者。
React.Component
React v3.13.0
版本引入了React.Component
API,允许你使用JavaScript的类(class
)来创建React组件。在React中使用class
创建的组件常常被称为React 类组件。
我们可以使用React.Component
来重构上面使用React.createClass()
方法创建的组件。
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
value: localStorage.getItem('userName') || '@大漠'
}
this.onChange = this.onChange.bind(this)
}
componentDidUpdate() {
localStorage.setItem('userName', this.state.value)
}
onChange(e) {
this.setState({
value: e.target.value
})
}
render() {
return (
<div className="card">
<h1>使用ES6 Class创建组件(React.Component)</h1>
<input
type="text"
value={this.state.value}
onChange={this.onChange}
/>
<p>Hello, {this.state.value} (^_^)!!!</p>
</div>
)
}
}
const rootElement = document.getElementById("app");
ReactDOM.render(<App />, rootElement);
使用JavaScript类编写React组件带有类构造函数constructor()
(主要用于React中设置初始状态或绑定方法)和render()
方法。React组件内部所有逻辑都来自于React.Component
。通过类组件中使用面向对象继承的组件。但是,不建议在更多的地方使用继承这个概念。相反,建议使用组合而不是继承。
在React中使用React.Component
创建组件,有几个重要的概念需要掌握。
构造函数 constructor()
使用类组件,可以在构造函数constructor()
内部将组件的状态初始化为实例(this
)上的状态属性。但是,根据ECMAScript规范,如果要扩展子类(即React.Component
),必须要先调用super()
,然后才能使用this
。具体来说,在使用React时,还必须记住将props
传递给super()
:
class App extends React.Component {
constructor(props) {
super(props)
// ...
}
// ...
}
自动绑定
当使用React.createClass
创建组件时,React会自动将所有方法绑定到组件的实例(this
)。而React.Component
并非如此,很多开发人员都意识到他们不知道this
关键字是如何工作的。因为必须记住类构造函数中的.bind()
方法(即.bind(this)
)。如果不这样做的话,浏览器会报“无法读取未定义的setState
属性”错误。
class App extends React.Component {
constructor(props) {
super(props)
//...
this.onChange = this.onChange.bind(this)
}
// ...
}
调用
super(props)
并要记住.bind(this)
方法是比较烦人,但这里并没有什么根本的错误。但当你一天要像这样处理很多次的时候,也会令人感到烦感。庆幸的是,在从createClass
切换到React.Component
之后不久,TC39就提出Class Fields相关的建议。
类字段(Class Fields)
类字段允许我们直接将实例属性作为属性添加到类上,而无需使用构造函数。这样一来,我们就不再需要使用构造函数来设置组件的初始状态,也不再需要在构造函数中使用.bind(this)
,因为我们可以使用箭头函数。
class App extends React.Component {
state = {
value: localStorage.getItem('userName') || '@w3cplus'
}
componentDidUpdate() {
localStorage.setItem('userName', this.state.value)
}
onChange = (e) => {
this.setState({
value: e.target.value
})
}
render () {
const {value} = this.state
return (
<div className="card">
<h1>使用React.Component创建组件(Class Fields)</h1>
<input
type="text"
value={value}
onChange={this.onChange}
/>
<p>Hello, {value} (^_^)!!!</p>
</div>
)
}
}
const rootElement = document.getElementById("app");
ReactDOM.render(<App />, rootElement);
如需转载,烦请注明出处:https://www.w3cplus.com/react/how-to-create-component-in-react.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!