學(xué)習(xí)React也有一段時間了,雖然天天都在圍繞著組件打轉(zhuǎn)轉(zhuǎn),但在React中怎么構(gòu)建組件呢并沒有去深入的了解。愛掏網(wǎng) - it200.com事實上呢?在React中的組件還是有些復(fù)雜的,從概念上來說就不簡單。愛掏網(wǎng) - it200.com比如說,類組件,函數(shù)組件,無狀態(tài)組件和高階組件等。愛掏網(wǎng) - it200.com另外創(chuàng)建組件的方式也有所不同,比如最早使用React.createClass
來創(chuàng)建組件,有了ES6之后使用extends React.Component
(借助ES6的class
特性)創(chuàng)建組件,而今天又流行使用函數(shù)(Hooks)方式來創(chuàng)建組件。愛掏網(wǎng) - it200.com那么他們之間如何創(chuàng)建組件,又有何區(qū)別呢?在這篇文章中我們就先來學(xué)習(xí)和探討在React中如何創(chuàng)建組件。愛掏網(wǎng) - it200.com
先來看React.createClass
如何創(chuàng)建組件?
如果你一直以來都在使用React的話,那么對React.createClass
這個API并不陌生。愛掏網(wǎng) - it200.com在React中,最初就是用這個API來創(chuàng)建React組件。愛掏網(wǎng) - it200.com將描述組件的所有信息都將作為對象傳遞給createClass
。愛掏網(wǎng) - it200.com
createClass
方法為開發(fā)人員提供了一個工廠方法(Factory Method),可以在不使用JavaScript 類的情況下創(chuàng)建React類組件。愛掏網(wǎng) - it200.com這是在ES之前創(chuàng)建React組件方法之一,因為在ES5中沒有可用的類語法:
const App = React.createClass({
getInitialState: function() {
return {
value: '大漠'
}
}
onChange: function(e) {
this.setState({
value: e.target.value
})
}
render: function() {
return (
使用 React.createClass 創(chuàng)建組件
Hello, {this.state.value} (^_^)!
)
}
})
const rootElement = document.getElementById("app");
ReactDOM.render(, rootElement);
createClass()
方法接受一個對象,該對象為React組件定義方法。愛掏網(wǎng) - it200.comgetInitialState()
函數(shù)用于為React組件設(shè)置初始狀態(tài),強(qiáng)制使用render()
方法在JSX中用于輸出;額外的方法(比如onChange
)是通過向?qū)ο髠鬟f更多的函數(shù)而添加的。愛掏網(wǎng) - it200.com
React中的生命周期也是可用的。愛掏網(wǎng) - it200.com例如,為了每次將值從input
中輸入存到瀏覽器的本地存儲中(localStorage
),我們可以使用componentDidUpdate()
生命周期,該方法是將一個函數(shù)傳遞給對象,對象鍵以React的生命周期方法命名。愛掏網(wǎng) - it200.com此外,當(dāng)組件接收到初始狀態(tài)時,可以從本地存儲中讀取該值:
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 (
使用React.createClass創(chuàng)建組件
Hello, {this.state.value} (^_^)!
)
}
})
const rootElement = document.getElementById("app");
ReactDOM.render(, rootElement);
這個示例具有本地存儲的功能,每當(dāng)重新加載或刷新瀏覽器時,當(dāng)組件第一次掛載時,應(yīng)該會顯示之前在input
中輸入的本地存儲的初始狀態(tài)。愛掏網(wǎng) - it200.com
React Mixins
React中引入了React Mixins,作為React的第一個可重用組件邏輯,這是一種高級模式。愛掏網(wǎng) - it200.com使用Mixin,可以將React組件的邏輯提取出來成為一個獨立對象。愛掏網(wǎng) - it200.com當(dāng)在組件中使用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 (
使用React Mixin和createClass創(chuàng)建組件
Hello, {this.state.value} (^_^)!!!
)
}
})
const rootElement = document.getElementById("app");
ReactDOM.render(, rootElement);
本例中,Mixin提供從本地存儲中讀取組件的初始狀態(tài),并使用setLocalStorage()
方法擴(kuò)展組件,該方法稍后將在實際組件中使用。愛掏網(wǎng) - it200.com為了使用Mixin更加靈活,我們可以使用一個函數(shù)來返回一個對象:
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')],
// ...
})
createClass()
是創(chuàng)建React組件的一種簡單而有效的方法。愛掏網(wǎng) - it200.comReact最初使用createClass
API的原因是,當(dāng)時JavaScript沒有內(nèi)置的class
。愛掏網(wǎng) - it200.com當(dāng)然,這種情況最終改變了。愛掏網(wǎng) - it200.comES6開始引入了class
這個關(guān)鍵字,也可以使用類來創(chuàng)建組件。愛掏網(wǎng) - it200.com這讓React進(jìn)入了一個兩難的境地,要么繼續(xù)使用createClass
,要么跟進(jìn)ES6,使用class
來創(chuàng)建組件。愛掏網(wǎng) - it200.com事實證明,React選擇了后者。愛掏網(wǎng) - it200.com
React v3.13.0
版本引入了React.Component
API,允許你使用JavaScript的類(class
)來創(chuàng)建React組件。愛掏網(wǎng) - it200.com在React中使用class
創(chuàng)建的組件常常被稱為React 類組件。愛掏網(wǎng) - it200.com
我們可以使用React.Component
來重構(gòu)上面使用React.createClass()
方法創(chuàng)建的組件。愛掏網(wǎng) - it200.com
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 (
使用ES6 Class創(chuàng)建組件(React.Component)
Hello, {this.state.value} (^_^)!!!
)
}
}
const rootElement = document.getElementById("app");
ReactDOM.render(, rootElement);
使用JavaScript類編寫React組件帶有類構(gòu)造函數(shù)constructor()
(主要用于React中設(shè)置初始狀態(tài)或綁定方法)和render()
方法。愛掏網(wǎng) - it200.comReact組件內(nèi)部所有邏輯都來自于React.Component
。愛掏網(wǎng) - it200.com通過類組件中使用面向?qū)ο罄^承的組件。愛掏網(wǎng) - it200.com但是,不建議在更多的地方使用繼承這個概念。愛掏網(wǎng) - it200.com相反,建議使用組合而不是繼承。愛掏網(wǎng) - it200.com
在React中使用React.Component
創(chuàng)建組件,有幾個重要的概念需要掌握。愛掏網(wǎng) - it200.com
構(gòu)造函數(shù) constructor()
使用類組件,可以在構(gòu)造函數(shù)constructor()
內(nèi)部將組件的狀態(tài)初始化為實例(this
)上的狀態(tài)屬性。愛掏網(wǎng) - it200.com但是,根據(jù)ECMAScript規(guī)范,如果要擴(kuò)展子類(即React.Component
),必須要先調(diào)用super()
,然后才能使用this
。愛掏網(wǎng) - it200.com具體來說,在使用React時,還必須記住將props
傳遞給super()
:
class App extends React.Component {
constructor(props) {
super(props)
// ...
}
// ...
}
自動綁定
當(dāng)使用React.createClass
創(chuàng)建組件時,React會自動將所有方法綁定到組件的實例(this
)。愛掏網(wǎng) - it200.com而React.Component
并非如此,很多開發(fā)人員都意識到他們不知道this
關(guān)鍵字是如何工作的。愛掏網(wǎng) - it200.com因為必須記住類構(gòu)造函數(shù)中的.bind()
方法(即.bind(this)
)。愛掏網(wǎng) - it200.com如果不這樣做的話,瀏覽器會報“無法讀取未定義的setState
屬性”錯誤。愛掏網(wǎng) - it200.com
class App extends React.Component {
constructor(props) {
super(props)
//...
this.onChange = this.onChange.bind(this)
}
// ...
}
類字段(Class Fields)
類字段允許我們直接將實例屬性作為屬性添加到類上,而無需使用構(gòu)造函數(shù)。愛掏網(wǎng) - it200.com這樣一來,我們就不再需要使用構(gòu)造函數(shù)來設(shè)置組件的初始狀態(tài),也不再需要在構(gòu)造函數(shù)中使用.bind(this)
,因為我們可以使用箭頭函數(shù)。愛掏網(wǎng) - it200.com
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 (
使用React.Component創(chuàng)建組件(Class Fields)
Hello, {value} (^_^)!!!
)
}
}
const rootElement = document.getElementById("app");
ReactDOM.render(, rootElement);
已支付,使用閱讀碼
* 請輸入閱讀碼(忘記閱讀碼?)