好程式設計師web前端培訓分享React學習筆記(二)
好程式設計師 web前端培訓分享 React學習筆記( 二 ) , 元件的資料掛載方式 , 屬性(props) props 是正常是外部傳入的,元件內部也可以透過一些方式來初始化的設定,屬性不能被元件自己更改,但是你可以透過父元件主動重新渲染的方式來傳入新的 props
屬性是描述性質、特點的,元件自己不能隨意更改。
之前的元件程式碼裡面有 props 的簡單使用,總的來說,在使用一個元件的時候,可以把引數放在標籤的屬性當中,所有的屬性都會作為元件 props 物件的鍵值。透過箭頭函式建立的元件,需要透過函式的引數來接收 props :
import React, { Component, Fragment } from 'react' import ReactDOM from 'react-dom' class Title extends Component {
render () {
return (
< h1 > 歡迎進入{ this .props.name}的世界 < /h1>
)
}} const Content = (props) => {
return (
< p > {props.name}是一個構建UI的庫 < /p>
)} class App extends Component {
render () {
return (
< Fragment >
< Title name = "React" />
< Content name = "React.js" />
< /Fragment>
)
}} ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
設定元件的預設props
import React, { Component, Fragment } from 'react' import ReactDOM from 'react-dom' class Title extends Component {
// 使用類建立的元件,直接在這裡寫static方法,建立defaultProps static defaultProps = {
name : 'React'
}
render () {
return (
< h1 > 歡迎進入{ this .props.name}的世界 < /h1>
)
}} const Content = (props) => {
return (
< p > {props.name}是一個構建UI的庫 < /p>
)} // 使用箭頭函式建立的元件,需要在這個元件上直接寫defaultProps屬性 Content.defaultProps = {
name : 'React.js' } class App extends Component {
render () {
return (
< Fragment >
{ /* 由於設定了defaultProps, 不傳props也能正常執行,如果傳遞了就會覆蓋defaultProps的值 */ }
< Title />
< Content />
< /Fragment>
)
}} ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
props.children
我們知道使用元件的時候,可以巢狀。要在自定義元件的使用巢狀結構,就需要使用 props.children 。在實際的工作當中,我們幾乎每天都需要用這種方式來編寫元件。
import React, { Component, Fragment } from 'react' import ReactDOM from 'react-dom' class Title extends Component {
render () {
return (
< h1 > 歡迎進入{ this .props.children}的世界 < /h1>
)
}} const Content = (props) => {
return (
< p > {props.children} < /p>
)} class App extends Component {
render () {
return (
< Fragment >
< Title > React < /Title>
< Content >< i > React.js < /i>是一個構建UI的庫</Content>
< /Fragment>
)
}} ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
使用prop-types檢查props
React其實是為了構建大型應用程式而生, 在一個大型應用中,根本不知道別人使用你寫的元件的時候會傳入什麼樣的引數,有可能會造成應用程式執行不了,但是不報錯。為了解決這個問題,React提供了一種機制,讓寫元件的人可以給元件的 props 設定引數檢查,需要安裝和使用 prop-types :
$ npm i prop-types -S
狀態(state)
狀態就是元件描述某種顯示情況的資料,由元件自己設定和更改,也就是說由元件自己維護,使用狀態的目的就是為了在不同的狀態下使元件的顯示不同(自己管理)
定義state
第一種方式
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component {
state = {
name : 'React' ,
isLiked : false
}
render () {
return (
< div >
< h1 > 歡迎來到{ this .state.name}的世界 < /h1>
< button >
{
this .state.isLiked ? '❤️取消' : ' 收藏'
}
< /button>
< /div>
)
}}ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
另一種方式(推薦)
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component {
constructor() {
super ()
this .state = {
name : 'React' ,
isLiked : false
}
}
render () {
return (
< div >
< h1 > 歡迎來到{ this .state.name}的世界 < /h1>
< button >
{
this .state.isLiked ? '❤️取消' : ' 收藏'
}
< /button>
< /div>
)
}}ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
this.props 和 this.state 是純js物件,在vue中,data屬性是利用 Object.defineProperty 處理過的,更改data的資料的時候會觸發資料的 getter 和 setter ,但是React中沒有做這樣的處理,如果直接更改的話,react是無法得知的,所以,需要使用特殊的更改狀態的方法 setState 。
setState
isLiked 存放在例項的 state 物件當中,元件的 render 函式內,會根據元件的 state 的中的 isLiked 不同顯示“取消”或“收藏”內容。下面給 button 加上了點選的事件監聽。
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component {
constructor() {
super ()
this .state = {
name : 'React' ,
isLiked : false
}
}
handleBtnClick = () => {
this .setState({
isLiked : !this .state.isLiked
})
}
render () {
return (
< div >
< h1 > 歡迎來到{ this .state.name}的世界 < /h1>
< button onClick = { this .handleBtnClick} >
{
this .state.isLiked ? '❤️取消' : ' 收藏'
}
< /button>
< /div>
)
}}ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
setState 有兩個引數
第一個引數可以是物件,也可以是方法return一個物件,我們把這個引數叫做 updater
· 引數是物件
this .setState({
isLiked : !this .state.isLiked})
· 引數是方法
this.setState((prevState, props) => {
return {
isLiked: !prevState.isLiked
}
})
注意的是這個方法接收兩個引數,第一個是上一次的state, 第二個是props
setState 是非同步的,所以想要獲取到最新的state,沒有辦法獲取,就有了第二個引數,這是一個可選的回撥函式
this .setState((prevState, props) => {
return {
isLiked : ! prevState.isLiked
}}, () => {
console.log( '回撥裡的' , this .state.isLiked)})console.log( 'setState外部的' , this .state.isLiked)
屬性vs狀態
相似點:
都是純js物件,都會觸發render更新,都具有確定性(狀態/屬性相同,結果相同)
不同點:
00001. 屬效能從父元件獲取,狀態不能
00002. 屬性可以由父元件修改,狀態不能
00003. 屬效能在內部設定預設值,狀態也可以
00004. 屬性不在元件內部修改,狀態要改
00005. 屬效能設定子元件初始值,狀態不可以
00006. 屬性可以修改子元件的值,狀態不可以
state 的主要作用是用於元件儲存、控制、修改自己的可變狀態。 state 在元件內部初始化,可以被元件自身修改,而外部不能訪問也不能修改。你可以認為 state 是一個區域性的、只能被元件自身控制的資料來源。 state 中狀態可以透過 this.setState 方法進行更新, setState 會導致元件的重新渲染。
props 的主要作用是讓使用該元件的父元件可以傳入引數來配置該元件。它是外部傳進來的配置引數,元件內部無法控制也無法修改。除非外部元件主動傳入新的 props ,否則元件的 props 永遠保持不變。
如果搞不清 state 和 props 的使用場景,記住一個簡單的規則: 儘量少地用 state ,多用 props 。
沒有 state 的元件叫無狀態元件(stateless component),設定了 state 的叫做有狀態元件(stateful component)。因為狀態會帶來管理的複雜性,我們儘量多地寫無狀態元件,儘量少地寫有狀態的元件。這樣會降低程式碼維護的難度,也會在一定程度上增強元件的可複用性。
##狀態提升
如果有多個元件共享一個資料,把這個資料放到共同的父級元件中來管理
受控元件與非受控元件
React元件的資料渲染是否被呼叫者傳遞的 props 完全控制,控制則為受控元件,否則非受控元件。
渲染資料
· 條件渲染
{
condition ? '❤️取消' : ' 收藏' }
· 列表渲染
// 資料 const people = [{
id : 1 ,
name : 'Leo' ,
age : 35 }, {
id : 2 ,
name : 'XiaoMing' ,
age : 16 }] // 渲染列表 {
people.map(person => {
return (
< dl key = {person.id} >
< dt > {person.name} < /dt>
< dd > age : {person.age} < /dd>
< /dl>
)
})}
React的高效依賴於所謂的 Virtual-DOM,儘量不碰 DOM。對於列表元素來說會有一個問題:元素可能會在一個列表中改變位置。要實現這個操作,只需要交換一下 DOM 位置就行了,但是React並不知道其實我們只是改變了元素的位置,所以它會重新渲染後面兩個元素(再執行 Virtual-DOM ),這樣會大大增加 DOM 操作。但如果給每個元素加上唯一的標識,React 就可以知道這兩個元素只是交換了位置,這個標識就是 key ,這個 key 必須是每個元素唯一的標識
· dangerouslySetHTML
對於富文字建立的內容,後臺拿到的資料是這樣的:
content = "<p>React.js是一個構建UI的庫</p>"
處於安全的原因,React當中所有表示式的內容會被轉義,如果直接輸入,標籤會被當成文字。這時候就需要使用 dangerouslySetHTML 屬性,它允許我們動態設定 innerHTML
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component {
constructor() {
super ()
this .state = {
content : "<p>React.js是一個構建UI的庫</p>"
}
}
render () {
return (
< div
// 注意這裡是兩個下下劃線 __html dangerouslySetInnerHTML = {{__html : this .state.content}}
/>
)
}}ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
事件處理
繫結事件
採用on+事件名的方式來繫結一個事件,注意,這裡和原生的事件是有區別的,原生的事件全是小寫 onclick , React裡的事件是駝峰 onClick , React的事件並不是原生事件,而是合成事件 。
事件handler的寫法
· 直接在render裡寫行內的箭頭函式(不推薦)
· 在元件內使用箭頭函式定義一個方法(推薦)
· 直接在元件內定義一個非箭頭函式的方法,然後在render裡直接使用 > (不推薦)
· 直接在元件內定義一個非箭頭函式的方法,然後在constructor裡bind(this)(推薦)
Event 物件
和普通瀏覽器一樣,事件handler會被自動傳入一個 event 物件,這個物件和普通的瀏覽器 event 物件所包含的方法和屬性都基本一致。不同的是 React中的 event 物件並不是瀏覽器提供的,而是它自己內部所構建的。它同樣具有 event.stopPropagation 、 event.preventDefault 這種常用的方法
事件的引數傳遞
· 在 render 裡呼叫方法的地方外面包一層箭頭函式
· 在 render 裡透過 this.handleEvent.bind(this, 引數) 這樣的方式來傳遞
· 透過 event 傳遞
· 比較推薦的是做一個子元件, 在父元件中定義方法,透過 props 傳遞到子元件中,然後在子元件件透過 this.props.method 來呼叫
##處理使用者輸入
import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component {
constructor() {
super ()
this .state = {
xing : '' ,
ming : ''
}
}
handleInputChange = (e) => {
this .setState({
[e.target.name] : e.target.value
})
}
render () {
const {
xing,
ming
} = this .state
return (
< div >
< label >
< span > 姓 :< /span>
< input
type = "text"
name = "xing"
value = {xing}
onChange = { this .handleInputChange}
/>
< /label>
< label >
< span > 名 :< /span>
< input
type = "text"
name = "ming"
value = {ming}
onChange = { this .handleInputChange}
/>
< /label>
< p > 歡迎您 : {xing}{ming} < /p>
< /div>
)
}}ReactDOM.render(
< App /> ,
document .getElementById( 'root' ))
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2688497/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師web前端培訓分享React學習筆記(三)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享React學習筆記(一)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享node學習筆記程式設計師Web前端筆記
- 好程式設計師web前端培訓分享HTMLCSS學習筆記BFC程式設計師Web前端HTMLCSS筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記Promise程式設計師Web前端JavaScript筆記Promise
- 好程式設計師web前端培訓分享JavaScript學習筆記cookie程式設計師Web前端JavaScript筆記Cookie
- 好程式設計師web前端培訓分享JavaScript學習筆記SASS程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓學習筆記Vue學習筆記之二程式設計師Web前端筆記Vue
- 好程式設計師web前端培訓分享JavaScript學習筆記之設計模式程式設計師Web前端JavaScript筆記設計模式
- 好程式設計師web前端培訓分享學習JavaScript程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript學習筆記分支結構程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記之正則程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記之陣列程式設計師Web前端JavaScript筆記陣列
- 好程式設計師web前端培訓JavaScript學習筆記DOM程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓JavaScript學習筆記--jQuery程式設計師Web前端JavaScript筆記jQuery
- 好程式設計師web前端培訓學習筆記Vue學習筆記一程式設計師Web前端筆記Vue
- 好程式設計師web前端培訓分享JavaScript學習筆記函式進階程式設計師Web前端JavaScript筆記函式
- 好程式設計師web前端培訓分享JavaScript學習筆記之ES5程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習指南程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript學習筆記閉包與繼承程式設計師Web前端JavaScript筆記繼承
- 好程式設計師web前端培訓分享JavaScript學習筆記ajax及ajax封裝程式設計師Web前端JavaScript筆記封裝
- 好程式設計師web前端培訓分享JavaScript學習筆記之迴圈結構程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享node學習筆記系列之四十一程式設計師Web前端筆記
- 好程式設計師web前端培訓分享JavaScript學習筆陣列的排序程式設計師Web前端JavaScript陣列排序
- 好程式設計師web前端培訓分享詳解JavaScript學習筆記建構函式程式設計師Web前端JavaScript筆記函式
- 好程式設計師web前端培訓分享之HTMLCSS學習筆記css3-多列程式設計師Web前端HTMLCSS筆記S3
- 好程式設計師web前端培訓分享HTMLCSS學習筆記css3選擇器程式設計師Web前端HTMLCSS筆記S3
- 好程式設計師web前端分享菜鳥Vue學習筆記(二)程式設計師Web前端Vue筆記
- 好程式設計師web前端培訓分享怎樣學好css?程式設計師Web前端CSS
- 好程式設計師web前端培訓分享之HTMLCSS學習筆記媒體查詢+ rem用法程式設計師Web前端HTMLCSS筆記REM
- 好程式設計師web前端分享Vue學習筆記(一)程式設計師Web前端Vue筆記
- 好程式設計師web前端培訓分享HTMLCSS學習之CSS基礎程式設計師Web前端HTMLCSS
- 好程式設計師web前端培訓分享CSS基礎知識學習程式設計師Web前端CSS
- 好程式設計師web前端培訓分享之uni-app學習筆記uni-app詳解程式設計師Web前端APP筆記
- 好程式設計師web前端培訓分享JavaScript框架J程式設計師Web前端JavaScript框架
- 好程式設計師web前端教程分享JavaScript學習筆記之Event事件二程式設計師Web前端JavaScript筆記事件
- 好程式設計師web前端培訓HTMLCSS學習筆記之頁面最佳化程式設計師Web前端HTMLCSS筆記
- web前端培訓分享node學習筆記Web前端筆記