摘要:殲轟運(yùn)殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)這里有個知識點(diǎn)需要知道這個一定要調(diào)用,這里相當(dāng)于調(diào)用了的。下面簡單實(shí)現(xiàn)一下殲轟運(yùn)殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)如果要修改只能使用如改變。殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)這樣一來,在頁面渲染前就初始化有值了,頁面也正常了。
每一個的地方,每一種的知識,每一種事物,都是從陌生到熟悉。在這個過程里面,或許能開闊眼界,增長見識,體驗(yàn)樂趣。一切都?xì)w于我們的心態(tài)與行動。1.前言
學(xué)習(xí)之路不可停止,最近在玩 React。也動手嘗試寫了一個實(shí)例。借此整理總結(jié)下初步學(xué)習(xí) React 的一些基礎(chǔ)知識。因?yàn)檫@幾天比較忙,沒那么多時間,所以實(shí)例和文章沒有很細(xì)致。如果大家發(fā)現(xiàn)文章有錯誤的地方,請多諒解。有什么更新的建議,歡迎在評論區(qū)指出。該文章主要是大概講下和快速上手使用,如果深入,要靠自己探索,后期我也會補(bǔ)充文章。
1.這里使用 React 版本是 16.42.預(yù)熱知識2.如果大家看的有點(diǎn)蒙圈,可能要去 React 上面看下 React 的基礎(chǔ)。
3.代碼已經(jīng)上傳到 Github 上面,需要的可以去進(jìn)行下載,歡迎 star react-demos。
4.建議大家看該文章的時候也打開編輯器,邊寫邊看,思路會清晰很多
學(xué)習(xí)React之前,一定要對下面兩個知識點(diǎn)有所了解。如果不了解下面的知識,請前往下面對應(yīng)的鏈接,進(jìn)行學(xué)習(xí)。
2-1.JSX學(xué)習(xí) React 實(shí)例之前,一定要對JSX有一定的了解。JSX 可以說是一個語法糖,React 使用來替代常規(guī)的 JavaScript。看起來很像 XML 的 JavaScript 語法擴(kuò)展。
JSX 不是必須的,如下兩段代碼,是完全等價的,但是使用JSX會更加的清晰,簡潔,易懂。
JSX
let el=守候ReactDOM.render( el, document.getElementById("example") );
HTML
let el=React.createElement("div",{className:"suthor"},"守候") ReactDOM.render( el, document.getElementById("example") );
關(guān)于 JSX 語法的更多內(nèi)容,大家請看 React JSX 。這里不做過多的介紹。
2-2.組件組件是 React 最重要的一個概念。比如下面的代碼,就可以說是一個組件。
class Author extends React.Component{ render(){ return (守候) } }
當(dāng)然也可以使用函數(shù)組件的方式定義。
function Author(props) { return守候; }
把組件掛在到頁面的 id 為 example 的一個 Dom 元素上面。
ReactDOM.render(, document.getElementById("example") );
上面這里,就是一個組件,這個組件只有一個元素。組件也可以由多個元素組成
class Author extends React.Component{ render(){ return (守候 男) } }
參考鏈接:React 組件。
3.實(shí)例這個例子的運(yùn)行效果如下,是一個非常簡單的實(shí)例。下面通過這個實(shí)例,接觸下 React 的一些基礎(chǔ)知識和使用方式。
3-1.渲染渲染其實(shí)上面例子就已經(jīng)有了,就是利用 render 函數(shù)返回一個組件。之后利用 ReactDOM.render 進(jìn)行掛載到頁面上的特定 Dom 元素里面。
class EquipmentList extends React.Component{ render(){ return ( ) } } //掛載到頁面里 id 為 example 的元素上面 ReactDOM.render(3-2.狀態(tài)和循環(huán), document.getElementById("example") );
上面是最基本的一個頁面布局,但是頁面是靜態(tài)的,不是根據(jù)數(shù)據(jù)渲染的。下面認(rèn)識下狀態(tài)和循環(huán),以數(shù)據(jù)驅(qū)動渲染。
首先來說下狀態(tài)
引用菜鳥教程的說法:React 把組件看成是一個狀態(tài)機(jī)(State Machines)。通過與用戶的交互,實(shí)現(xiàn)不同狀態(tài),然后渲染 UI,讓用戶界面和數(shù)據(jù)保持一致。React 里,只需更新組件的 state,然后根據(jù)新的 state 重新渲染用戶界面(不要操作 DOM)。
我們把上面的代碼,稍微改下,給組件加上狀態(tài)。
class EquipmentList extends React.Component{ constructor(){ super(); this.state={ post1:"殲20", post2:"轟6K", post3:"運(yùn)20", } } render(){ return ( ) } } ReactDOM.render(, document.getElementById("example") );
這里有3個知識點(diǎn)需要知道1.super(); 這個一定要調(diào)用,這里相當(dāng)于調(diào)用了 React.Component 的 constructor。目的就是初始化 React 組件。
2.this.state 就是組件的狀態(tài)
3.render 方法里面,輸入的是 state (也可以是 props)。輸出的就是組件。
頁面效果完全一樣,至于狀態(tài)的修改等,下面再實(shí)例再提及。
但是這樣寫代碼顯然是不優(yōu)雅的,如果數(shù)據(jù)一多,工作量就很大,就應(yīng)該使用循環(huán)進(jìn)行渲染。下面把代碼改下。
class EquipmentList extends React.Component{ constructor(){ super(); this.state={ equipmentList:[ { id:1, title:"殲20" }, { id:2, title:"轟6K" }, { id:3, title:"運(yùn)20" } ], } } render(){ return ( ) } } ReactDOM.render(, document.getElementById("example") );
可能大家會有疑問,為什么li要帶上 key 這個屬性。是因?yàn)?React 是使用 key 屬性來標(biāo)志列表中的所有元素,當(dāng)列表數(shù)據(jù)發(fā)生變化時,React 通過 key 可以更快的知道哪些元素發(fā)生了變化,從而只重新渲染發(fā)生變化的元素,提高效率和性能。在列表里面 key 需要唯一,一般是使用 id 作為 key 值,不建議使用 index 作為 key 值。因?yàn)槿绻斜戆l(fā)生了刪除,插入等操作,列表要重排。index 值會改變,可能會影響渲染的效率和性能。3-3.事件
接下來就給組件添加時間,點(diǎn)擊 a 元素的時候,比如點(diǎn)擊‘殲擊機(jī)’,就應(yīng)該顯示 equipmentList 里面 title 等于‘殲20’的數(shù)據(jù),點(diǎn)擊‘轟炸機(jī)’,就應(yīng)該顯示 equipmentList 里面 title 等于‘轟6K’的數(shù)據(jù)......
實(shí)現(xiàn)這個需求,其實(shí)很簡單,就是新建一個狀態(tài) equipmentListNow ,組件里面只遍歷 equipmentListNow。點(diǎn)擊‘殲擊機(jī)’,就把 equipmentList 里面 title ‘殲20’的數(shù)據(jù)賦值給postListNow,點(diǎn)擊‘轟炸機(jī)’,就把 equipmentList 里面 title 等于‘轟6K’的數(shù)據(jù)賦值給postListNow......。
下面簡單實(shí)現(xiàn)一下
class EquipmentList extends React.Component{ constructor(){ super(); this.state={ equipmentList:[ { id:1, title:"殲20" }, { id:2, title:"轟6K" }, { id:3, title:"運(yùn)20" } ], equipmentListNow:[] } } switchTab(id){ let _list=this.state.equipmentList.filter(item=>item.id===id); this.setState({ equipmentListNow:_list }) } render(){ return ({ this.switchTab(1); }}>殲擊機(jī) { this.switchTab(2); }}>轟炸機(jī) { this.switchTab(3); }}>運(yùn)輸機(jī)) } } ReactDOM.render({this.state.equipmentListNow.map(item=>
- {item.title}
)}, document.getElementById("example") );
如果要修改 state ,只能使用如: this.setState({equipmentListNow:_list}) 改變。切記不能出現(xiàn)如下寫法:this.equipmentListNow=_list;
跑起來了,沒報錯,但是頁面上一開始列表沒有被渲染出來,要點(diǎn)擊的時候才有特定的數(shù)據(jù)出來(點(diǎn)擊第一章的a,出現(xiàn)第一章的數(shù)據(jù),以此類推)。原因想必大家也知道,因?yàn)樵陧撁娉跏蓟臅r候,equipmentListNow 只是一個空數(shù)組,所以正確的做法是在頁面初始化的時候,就把 equipmentList 的值賦給 equipmentListNow。頁面初始化賦值,就是下面組件生命周期的內(nèi)容了。
3-4.生命周期為了讓頁面加載后,equipmentListNow 能有初始化的內(nèi)容,那么需要在生命周期函數(shù)里面把 equipmentList 的值賦給 equipmentListNow。
至于生命周期,這里不展開講,大家可以看下文檔:React 組件生命周期。
大家應(yīng)該知道,這個初始化賦值操作,應(yīng)該在渲染前就完成。如果在渲染后再操作,那么就相當(dāng)于頁面渲染了第二次。所以我們現(xiàn)在用到的生命周期函數(shù)是 componentWillMount 。
class EquipmentList extends React.Component{ constructor(){ super(); this.state={ equipmentList:[ { id:1, title:"殲擊機(jī)" }, { id:2, title:"轟炸機(jī)" }, { id:3, title:"運(yùn)輸機(jī)" } ], equipmentListNow:[] } } switchTab(id){ let _list=this.state.equipmentList.filter(item=>item.id===id); this.setState({ equipmentListNow:_list }) } componentDidMount(){ let _list=this.state.equipmentList; this.setState({ equipmentListNow:_list }) } render(){ return ({ this.switchTab(1); }}>殲擊機(jī) { this.switchTab(2); }}>轟炸機(jī) { this.switchTab(3); }}>運(yùn)輸機(jī)) } } ReactDOM.render({this.state.equipmentListNow.map(item=>
- {item.title}
)}, document.getElementById("example") );
這樣一來,equipmentListNow 在頁面渲染前就初始化有值了,頁面也正常了。
3-5.組件樣式上面的組件,一行 CSS 都沒寫,看著就特別難看。下面就添加些樣式。
方式1:最簡單的方式就是,就是給組件起 class 。在外部寫上 CSS 樣式。
CSS 代碼
body{ font-family: "微軟雅黑"; } ul{ margin: 0; padding: 0; } .post-box{ width: 600px; margin: 30px auto; } .post-box a{ display: inline-block; font-size: 14px; margin-right: 10px; width: 80px; height: 30px; line-height: 30px; text-align: center; background: #09f; color: #fff; text-decoration: none; } .post-box li{ list-style-type: none; line-height: 40px; padding-left: 10px; border-bottom: 1px solid #ccc; }
JS 代碼
在 js class 是關(guān)鍵字,所以要給元素設(shè)置 class 屬性,需要用 className
render() { return ( {/*給div增加class*/}...) }
方式2:由于 React 的機(jī)制,所以很多時候會使用 css-in-js 這種方式,設(shè)置元素的樣式,簡單來說就是設(shè)置元素的內(nèi)聯(lián)樣式。
render() { return ({/*給a設(shè)置內(nèi)聯(lián)樣式*/} { this.switchTab(1); }} style={{background:"#f90"}}>殲擊機(jī) { this.switchTab(2); }} style={{background:"#f00"}}>轟炸機(jī) { this.switchTab(3); }} style={{background:"#0f0"}}>運(yùn)輸機(jī)) }{this.state.equipmentListNow.map(item =>
- {item.title}
)}
css-in-js 的另一種寫法是:聲明樣式變量
let _style={ background:"#09f", color:"#f3f201" }
render() { return (3-6.有狀態(tài)組件和無狀態(tài)組件{/*給a設(shè)置內(nèi)聯(lián)樣式*/} { this.switchTab(1); }} style={_style}>殲擊機(jī) { this.switchTab(2); }} style={_style}>轟炸機(jī) { this.switchTab(3); }} style={_style}>運(yùn)輸機(jī)) }{this.state.equipmentListNow.map(item =>
- {item.title}
)}
大家可以看到,上面的組件,是有一個狀態(tài) state 的。但大家看了文章開始的例子就知道,并不是所有的組件都是需要 state 的。根據(jù)有無 state 。可以把組件區(qū)分為有狀態(tài)組件和無狀態(tài)組件。把有狀態(tài)組件和無狀態(tài)組件合理利用,分工合作,可以說是用好 React 的第一步,下面簡單分析下。
不難發(fā)現(xiàn),上面 EquipmentList 組件復(fù)用性不強(qiáng)。想要復(fù)用,必須把代碼拷貝過去,然后再修改 equipmentList 這個狀態(tài)。
大家應(yīng)該知道 EquipmentList 要想復(fù)用,里面的數(shù)組不能寫死,只能由外部傳入,EquipmentList 通過 props 獲取數(shù)據(jù)。
既然說到了 props 就順便提下,props 的作用就是把父組件的值傳給子組件。props 是一個對象。如下
下面引用 2-2 的一個例子。 ReactDOM.render(, document.getElementById("example") );
那么 Author 里面收到的 props 就是
props={ name:"守候", gender:"男" }
使用方式也很簡單
class Author extends React.Component{ render(){ return ({this.props.name} {this.props.gender}) } }
引用菜鳥教程說法:state 和 props 主要的區(qū)別在于 props 是不可變的,而 state 可以根據(jù)與用戶交互來改變。這就是為什么有些容器組件需要定義 state 來更新和修改數(shù)據(jù)。 而子組件只能通過 props 來傳遞數(shù)據(jù)。
說了這么多,下面修改下,把 EquipmentList 封裝成一個能復(fù)用的組件。
class EquipmentList extends React.Component { constructor(props) { super(props); this.state = { //根據(jù)props獲取數(shù)據(jù) equipmentList: this.props.list, equipmentListNow: [] } } switchTab(id) { let _list = this.state.equipmentList.filter(item => item.id === id); this.setState({ equipmentListNow: _list }) } componentDidMount() { let _list = this.state.equipmentList; this.setState({ equipmentListNow: _list }) } render() { return ({ this.switchTab(1); }}>殲擊機(jī) { this.switchTab(2); }}>轟炸機(jī) { this.switchTab(3); }}>運(yùn)輸機(jī)) } }{this.state.equipmentListNow.map(item =>
- {item.title}
)}
這里有一個要注意的點(diǎn) 在 constructor 里面,我寫的是 super(props) 不是之前那樣的 super() 。這樣的寫的原因就是為了在 constructor 里面可以使用 this.props。如下代碼
constructor(props) { super(props); this.state = { //根據(jù)props獲取數(shù)據(jù) equipmentList: this.props.list, equipmentListNow: [] } }
如不需要用 this.props 。可以直接寫 super(),當(dāng)然寫 super(props) 也沒錯。
constructor(props) { super(); this.state = { //根據(jù)props獲取數(shù)據(jù) equipmentList: props.list, equipmentListNow: [] } }
說了這么多,下面看下怎么使用。
使用方式1,這里只做一個說明,這樣子寫實(shí)際是沒什么意思的。
let equipmentList = [ { id: 1, title: "殲20" }, { id: 2, title: "轟6K" }, { id: 3, title: "運(yùn)20" } ] ReactDOM.render(, document.getElementById("example") );
使用方式2
class Example2 extends React.Component { constructor(props) { super(props); this.state = { equipmentList: [ { id: 1, title: "殲20-量產(chǎn)型號" }, { id: 2, title: "轟6K-量產(chǎn)型號" }, { id: 3, title: "運(yùn)20-量產(chǎn)型號" } ], } } componentDidMount() { let _list = this.state.equipmentList; //兩秒后更新數(shù)據(jù) setTimeout(() => { _list.forEach((item,index)=>{ item.title="其實(shí)這是一艘航空母艦"+index; }); this.setState({ equipmentList: _list }) }, 2000) } render(){ return () } } ReactDOM.render( , document.getElementById("example2") );
這樣一來,EquipmentList 變成了無狀態(tài)組件,Example2 變成了有狀態(tài)組件。分工方面,EquipmentList 不操作數(shù)據(jù)的變化,只管數(shù)據(jù)的渲染;Example2 不關(guān)注如何渲染,只控制數(shù)據(jù)變化,每次變化,使用 setState 更新數(shù)據(jù),EquipmentList 的渲染結(jié)果就會改變。
看到這可能大家也有感悟了,一般而言,一個頁面上絕大部分應(yīng)該是無狀態(tài)組件,少部分是有狀態(tài)組件。
最后提一點(diǎn),可能大家也有會疑問,如果 props 很多都是重復(fù)的值,可不可以設(shè)置一個默認(rèn)值,就可以少傳些參數(shù)。答案是可以的,比如下面代碼,掛載的時候 EquipmentList 沒有傳值,但是能渲染出來,因?yàn)槭褂昧?defaultProps 設(shè)置 props 的默認(rèn)值。
class EquipmentList extends React.Component { constructor(props) { super(props); this.state = { //根據(jù)props獲取數(shù)據(jù) equipmentList: this.props.list, equipmentListNow: [] } } switchTab(id) { let _list = this.state.equipmentList.filter(item => item.id === id); this.setState({ equipmentListNow: _list }) } componentDidMount() { let _list = this.state.equipmentList; this.setState({ equipmentListNow: _list }) } render() { return (4.小結(jié){ this.switchTab(1); }}>殲擊機(jī) { this.switchTab(2); }}>轟炸機(jī) { this.switchTab(3); }}>運(yùn)輸機(jī)) } } //設(shè)置 props 默認(rèn)值 EquipmentList.defaultProps={ list:[ { id: 1, title: "殲20" }, { id: 2, title: "轟6K" }, { id: 3, title: "運(yùn)20" } ] } ReactDOM.render({this.state.equipmentListNow.map(item =>
- {item.title}
)}, document.getElementById("example") );
好了,這幾天對 React 學(xué)習(xí)的一些總結(jié),就暫時告一段落了。該文章只是針對 React 實(shí)現(xiàn)一個非常簡單的實(shí)例,也很基礎(chǔ)。如果要深入,就要大家各自去努力了,在往后深入學(xué)習(xí)里面,我也會繼續(xù)寫文章,分享。希望和大家有更多的交流,如果大家對文章有什么看法和建議,歡迎指點(diǎn)。
-------------------------華麗的分割線--------------------
想了解更多,和我交流,內(nèi)推職位,請?zhí)砑游椅⑿拧;蛘哧P(guān)注我的微信公眾號:守候書閣
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/97074.html
摘要:殲轟運(yùn)殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)這里有個知識點(diǎn)需要知道這個一定要調(diào)用,這里相當(dāng)于調(diào)用了的。下面簡單實(shí)現(xiàn)一下殲轟運(yùn)殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)如果要修改只能使用如改變。殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)殲擊機(jī)轟炸機(jī)運(yùn)輸機(jī)這樣一來,在頁面渲染前就初始化有值了,頁面也正常了。 每一個的地方,每一種的知識,每一種事物,都是從陌生到熟悉。在這個過程里面,或許能開闊眼界,增長見識,體驗(yàn)樂趣。一切都?xì)w于我們的心態(tài)與行動。 1.前言 ...
摘要:在有了基礎(chǔ)之后,進(jìn)一步學(xué)習(xí)內(nèi)容包括框架。前端學(xué)習(xí)交流群禁止閑聊,非喜勿進(jìn)。代碼提交前必須做的三個事情檢查所有變更跑一邊單元測試手動運(yùn)行一遍所有 網(wǎng)站開發(fā)開發(fā)大致分為前端和后端,前端主要負(fù)責(zé)實(shí)現(xiàn)視覺和交互效果,以及與服務(wù)器通信,完成業(yè)務(wù)邏輯。其核心價值在于對用戶體驗(yàn)的追求。可以按如下思路學(xué)習(xí)系統(tǒng)學(xué)習(xí): 基礎(chǔ)知識: html + css 這部分建議在?w3school 在線教程上學(xué)習(xí),邊...
摘要:在有了基礎(chǔ)之后,進(jìn)一步學(xué)習(xí)內(nèi)容包括框架。前端學(xué)習(xí)交流群禁止閑聊,非喜勿進(jìn)。代碼提交前必須做的三個事情檢查所有變更跑一邊單元測試手動運(yùn)行一遍所有 網(wǎng)站開發(fā)開發(fā)大致分為前端和后端,前端主要負(fù)責(zé)實(shí)現(xiàn)視覺和交互效果,以及與服務(wù)器通信,完成業(yè)務(wù)邏輯。其核心價值在于對用戶體驗(yàn)的追求。可以按如下思路學(xué)習(xí)系統(tǒng)學(xué)習(xí): 基礎(chǔ)知識: html + css 這部分建議在?w3school 在線教程上學(xué)習(xí),邊...
摘要:我的第一個項目是一個基于和的后臺管理系統(tǒng),當(dāng)時我還沒有任何的前端開發(fā)知識,時間也比較緊,就在學(xué)習(xí)和的基礎(chǔ)后,有針對性的對和進(jìn)行了了解。 第一篇博文,寫在從零開始學(xué)前端的兩個月后,期間經(jīng)過了春節(jié),之后又經(jīng)歷了一些動蕩。算是在邊做邊學(xué)中堅持下來,現(xiàn)在基本上可以完成一些業(yè)務(wù)邏輯上的開發(fā)工作。想到應(yīng)該總結(jié)一下這兩個月的學(xué)習(xí),也是對自己的知識掌握情況做一個梳理。 我的第一個項目是一個基于vue和...
閱讀 2474·2021-11-19 09:59
閱讀 1995·2019-08-30 15:55
閱讀 936·2019-08-29 13:30
閱讀 1339·2019-08-26 10:18
閱讀 3088·2019-08-23 18:36
閱讀 2390·2019-08-23 18:25
閱讀 1164·2019-08-23 18:07
閱讀 440·2019-08-23 17:15