詳解React之父子組件傳遞和其它一些要點(diǎn)
react是R系技術(shù)棧中最基礎(chǔ)同時(shí)也是最核心的一環(huán),2年不到獲取了62.5k star(截止到目前),足可見其給力程度。下面對(duì)一些react日常開發(fā)中的注意事項(xiàng)進(jìn)行羅列。
React的組件生命周期
react主要思想是構(gòu)建可復(fù)用組件來構(gòu)建用戶界面。在react里面一切皆組件。每個(gè)組件里面都是有自己的生命周期,這個(gè)生命周期規(guī)定了組件的狀態(tài)和方法,分別在哪個(gè)階段執(zhí)行。下面附上一張React的生命周期圖:
組件第一階段:初始化、渲染以及裝載完成;
組件第二階段:組件運(yùn)行時(shí)候的狀態(tài) ①:狀態(tài)變化引發(fā)組件的更新和重新渲染到更新完成
②:父組件屬性變化引發(fā)組件的更新(是常見的組件之間傳遞數(shù)據(jù)和同步狀態(tài)的手段):比如父組件登錄了,子組件也需變成登錄狀態(tài)
組件第三階段:卸載組件
JSX 語法
const names = ['Alice', 'Emily', 'Kate']; ReactDOM.render( <div> { names.map((name) => { return <div>Hello, {name}!</div> }) } </div>, document.getElementById('example') );
JSX 的基本語法規(guī)則:遇到 HTML 標(biāo)簽(以<
開頭),就用 HTML 規(guī)則解析;遇到代碼塊(以{
開頭),就用 JavaScript 規(guī)則解析。
所以給jsx添加注釋只要這樣子:
{/* 。。。 */}
父組件傳向子組件
子: var HelloMessage = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; } }); --------------------------------------- 父: ReactDOM.render( <HelloMessage name="Muyy" />, document.getElementById('example') );
變量HelloMessage
就是相當(dāng)于一個(gè)子組件類。通過this.props.name獲取到了Muyy。
另外注意
- 所有組件類都必須有自己的
render
方法,用于輸出組件。 - 組件類的第一個(gè)字母必須大寫,否則會(huì)報(bào)錯(cuò),比如
HelloMessage
不能寫成helloMessage
- 組件類只能包含一個(gè)頂層標(biāo)簽
class
屬性需要寫成className
,for
屬性需要寫成htmlFor
,這是因?yàn)?code>class和for
是 JavaScript 的保留字
子組件傳向父(爺)組件
其實(shí)很簡(jiǎn)單,概括起來就是:react中state改變了,組件才會(huì)update。父組件寫好state和處理該state的函數(shù),同時(shí)將函數(shù)名通過props屬性值的形式傳入子,子調(diào)用父的函數(shù),同時(shí)引起state變化。
例子1.這里如下圖,用戶郵箱為父,綠色框?yàn)樽印?父組件為用戶輸入的郵箱設(shè)好state,即“{email: ''}”,同時(shí)寫好處理state的函數(shù),即“handleEmail”,這兩個(gè)名稱隨意起;再將函數(shù)以props的形式傳到子組件,子組件只需在事件發(fā)生時(shí),調(diào)用父組件傳過來的函數(shù)即可。
//子組件 var Child = React.createClass({ render: function(){ return ( <div> 請(qǐng)輸入郵箱:<input onChange={this.props.handleEmail}/> </div> ) } }); //父組件,此處通過event.target.value獲取子組件的值 var Parent = React.createClass({ getInitialState: function(){ return { email: '' } }, handleEmail: function(event){ this.setState({email: event.target.value}); }, render: function(){ return ( <div> <div>用戶郵箱:{this.state.email}</div> <Child name="email" handleEmail={this.handleEmail.bind(this)}/> </div> ) } }); React.render( <Parent />, document.getElementById('test') );
例子2.有時(shí)候往往需要對(duì)數(shù)據(jù)做處理,再傳給父組件,比如過濾或者自動(dòng)補(bǔ)全等等,下面的例子對(duì)用戶輸入的郵箱做簡(jiǎn)單驗(yàn)證,自動(dòng)過濾非數(shù)字、字母和"@."以外的字符。
//子組件,handleVal函數(shù)處理用戶輸入的字符,再傳給父組件的handelEmail函數(shù) var Child = React.createClass({ handleVal: function() { var val = this.refs.emailDom.value; val = val.replace(/[^0-9|a-z|\@|\.]/ig,""); this.props.handleEmail(val); }, render: function(){ return ( <div> 請(qǐng)輸入郵箱:<input ref="emailDom" onChange={this.handleVal}/> </div> ) } }); //父組件,通過handleEmail接受到的參數(shù),即子組件的值 var Parent = React.createClass({ getInitialState: function(){ return { email: '' } }, handleEmail: function(val){ this.setState({email: val}); }, render: function(){ return ( <div> <div>用戶郵箱:{this.state.email}</div> <Child name="email" handleEmail={this.handleEmail.bind(this)}/> </div> ) } }); React.render( <Parent />, document.getElementById('test') );
例子3.如果還存在孫子組件的情況呢?如下圖,黑框?yàn)楦?,綠框?yàn)樽?,紅框?yàn)閷O,要求子孫的數(shù)據(jù)都傳給爺爺。原理一樣的,只是父要將爺爺對(duì)孫子的處理函數(shù)直接傳下去。
//孫子,將下拉選項(xiàng)的值傳給爺爺 var Grandson = React.createClass({ render: function(){ return ( <div>性別: <select onChange={this.props.handleSelect}> <option value="男">男</option> <option value="女">女</option> </select> </div> ) } }); //子,將用戶輸入的姓名傳給爹 //對(duì)于孫子的處理函數(shù),父只需用props傳下去即可 var Child = React.createClass({ render: function(){ return ( <div> 姓名:<input onChange={this.props.handleVal}/> <Grandson handleSelect={this.props.handleSelect}/> </div> ) } }); //父組件,準(zhǔn)備了兩個(gè)state,username和sex用來接收子孫傳過來的值,對(duì)應(yīng)兩個(gè)函數(shù)handleVal和handleSelect var Parent = React.createClass({ getInitialState: function(){ return { username: '', sex: '' } }, handleVal: function(event){ this.setState({username: event.target.value}); }, handleSelect: function(event) { this.setState({sex: event.target.value}); }, render: function(){ return ( <div> <div>用戶姓名:{this.state.username}</div> <div>用戶性別:{this.state.sex}</div> <Child handleVal={this.handleVal.bind(this)} handleSelect={this.handleSelect.bind(this)}/> </div> ) } }); React.render( <Parent />, document.getElementById('test') );
getDefaultProps && getInitialState
getDefaultProps
方法可以用來設(shè)置組件屬性的默認(rèn)值
var MyTitle = React.createClass({ getDefaultProps : function () { return { title : 'Hello World' }; }, render: function() { return <h1> {this.props.title} </h1>; } }); ReactDOM.render( <MyTitle />, document.body );
getInitialState 方法可以用來設(shè)置初始狀態(tài)
getInitialState: function() { return {liked: false}; },
獲取真實(shí)的DOM節(jié)點(diǎn)
從組件獲取真實(shí) DOM 的節(jié)點(diǎn),這時(shí)就要用到ref
屬性
var MyComponent = React.createClass({ handleClick: function() { this.refs.myTextInput.focus(); }, render: function() { return ( <div> <input type="text" ref="myTextInput" /> <input type="button" value="Focus the text input" onClick={this.handleClick} /> </div> ); } }); ReactDOM.render( <MyComponent />, document.getElementById('example') );
上面代碼中,組件MyComponent
的子節(jié)點(diǎn)有一個(gè)文本輸入框,用于獲取用戶的輸入。這時(shí)就必須獲取真實(shí)的 DOM 節(jié)點(diǎn),虛擬 DOM 是拿不到用戶輸入的。為了做到這一點(diǎn),文本輸入框必須有一個(gè)ref
屬性,然后this.refs.[refName]
就會(huì)返回這個(gè)真實(shí)的 DOM 節(jié)點(diǎn)。
需要注意的是,由于this.refs.[refName]
屬性獲取的是真實(shí) DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個(gè)屬性,否則會(huì)報(bào)錯(cuò)。上面代碼中,通過為組件指定Click
事件的回調(diào)函數(shù),確保了只有等到真實(shí) DOM 發(fā)生Click
事件之后,才會(huì)讀取this.refs.[refName]
屬性。
React 組件支持很多事件,除了Click
事件以外,還有KeyDown
、Copy
、Scroll
等,完整的事件清單請(qǐng)查看官方文檔。
子組件傳向父組件的另一種思路
父組件調(diào)用子組件的state、function,除了上面介紹的方法之外,也可以通過ref屬性實(shí)現(xiàn)。推薦使用這種方式進(jìn)行子組件向父組件的傳遞。舉個(gè)簡(jiǎn)單的示范:
export default class 父組件a extends React.Component { constructor(props) { super(props) } render() { return ( <子組件b ref={r => this.bbbb =r} // bbbb自定義名字 /> ) } }
經(jīng)過這樣處理后后,現(xiàn)在父組件a中可以通過this.bbbb.state.xxx獲取子組件的xxx狀態(tài),也可以通過this.bbbb.xxx獲取子組件的xxx方法。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React實(shí)現(xiàn)動(dòng)態(tài)輪播圖的使用示例
輪播組件是常見的一種方式,用來展示圖像、信息或者是廣告,本文就來介紹一下React實(shí)現(xiàn)動(dòng)態(tài)輪播圖的使用示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12react antd checkbox實(shí)現(xiàn)全選、多選功能
目前好像只有table組件有實(shí)現(xiàn)表格數(shù)據(jù)的全選功能,如果說對(duì)于list,card,collapse等其他組件來說,需要自己結(jié)合checkbox來手動(dòng)實(shí)現(xiàn)全選功能,這篇文章主要介紹了react antd checkbox實(shí)現(xiàn)全選、多選功能,需要的朋友可以參考下2024-07-07使用react-activation實(shí)現(xiàn)keepAlive支持返回傳參
本文主要介紹了使用react-activation實(shí)現(xiàn)keepAlive支持返回傳參,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05jsoneditor二次封裝實(shí)時(shí)預(yù)覽json編輯器組件react版
這篇文章主要為大家介紹了jsoneditor二次封裝實(shí)時(shí)預(yù)覽json編輯器組件react版示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10React實(shí)現(xiàn)文件上傳和斷點(diǎn)續(xù)傳功能的示例代碼
這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)文件上傳和斷點(diǎn)續(xù)傳功能的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02react滾動(dòng)加載useInfiniteScroll?詳解
使用useInfiniteScroll?hook可以處理檢測(cè)用戶何時(shí)滾動(dòng)到頁面底部的邏輯,并觸發(fā)回調(diào)函數(shù)以加載更多數(shù)據(jù),它還提供了一種簡(jiǎn)單的方法來管理加載和錯(cuò)誤消息的狀態(tài),今天通過實(shí)例代碼介紹下react滾動(dòng)加載useInfiniteScroll?相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧2023-09-09