React中父子組件通信詳解
父組件向子組件通信
在父組件中,為子組件添加屬性數據,即可實現父組件向子組件通信。傳遞的數據可以分成兩類
子組件是作為屬性來接收這些數據的
第一類就是數據:變量,對象,屬性數據,狀態數據等等
這些數據發生改變,子組件接收的屬性數據就發生瞭改變。
第二類就是方法:父組件可以向子組件傳遞屬性方法,子組件接收方法,並可以在組件內執行,有兩種執行方式
註意:父組件傳給子組件的方法是不能執行的,執行瞭相當於將方法的返回值傳遞給子組件。
第一種 作為事件回調函數執行
參數默認就是事件對象
this默認指向undefined,因此我們要改變this指向
如果在子組件中改變,
this指向子組件
bind方式傳遞的參數在事件對象之前
如果在父組件中改變(工作中常用
)
this指向父組件瞭
此時子組件不論如何綁定,都指向父組件
bind方式傳遞的參數會在子組件傳遞的參數之前
參數順序:父組件參數,子組件參數,事件對象
第二種 在子組件方法中執行
默認沒有參數,使用什麼可以傳遞什麼
this默認指向子組件屬性對象(this.props)
此時我們要在父組件中綁定this,就指向瞭父組件
我們既可以訪問父組件實例化對象,也可以訪問子組件實例化對象,
我們既可以在子組件中傳遞參數,也可以在父組件中傳遞參數
有一種簡寫方式(工作中常用
)
直接在事件回調函數中,定義箭頭函數,並執行父組件方法:
// 定義父組件slider class Slider extends Component { // 構造函數 constructor(props) { super(props); // 初始化狀態 this.state = { title: '返回頂部' } } // 父組件方法 parentMethod() { console.log(this, arguments) } render() { return ( <div className="slider"> {/*字符串*/} {/*<GoTop text="網址導航"></GoTop>*/} {/*屬性數據*/} {/*<GoTop text={this.props.title}></GoTop>*/} {/*狀態數據*/} {/*<GoTop text={this.state.title}></GoTop>*/} {/*傳遞方法*/} <GoTop text={this.state.title} method={this.parentMethod.bind(this, 200, 'parent')}></GoTop> {/*<GoTop text={this.state.title} method={this.parentMethod}></GoTop>*/} </div> ) } } // 定義組件 class GoTop extends Component { // 定義方法 childMethod(e) { // 執行父組件方法 this.props.method(200, e); } // 4 渲染虛擬DOM render() { // console.log(this.props) // 綁定事件 // return <span onClick={this.props.method.bind(this, 100, 'child')}>{this.props.text}</span> // 在子組件方法中執行 // return <span onClick={this.childMethod.bind(this)}>{this.props.text}</span> // 簡便寫法 return <span onClick={e => this.props.method(e)}>{this.props.text}</span> } }
存在期
組件創建完成,一旦屬性數據或者狀態數據發生改變,組件就會進入存在期,共分五個階段
第一個階段 組件即將接收新的屬性數據
componnetWillReceiveProps方法
第一個參數表示新的
屬性數據
組件實例化對象上的是舊的屬性數據
數據還沒有更新,
隻有當屬性數據發生改變,才會執行該方法,狀態數據改變不會執行
,直接進入第二個階段
作用:用屬性數據去更新狀態數據,實現數據由外部流入內部
第二個階段 組件是否應該更新
shouldComponentUpdate方法
第一個參數表示新的
屬性數據
第二個參數表示新的
狀態數據
組件實例化對象上的是舊的屬性數據
組件實例化對象上的是舊的狀態數據
必須有返回值,表示是否可以更新
true 可以更新
false 不能更新
工作中,我們常常比較
參數中的屬性數據是否與組件實例化對象中屬性數據是否不相等,或者
參數中的狀態數據是否與組件實例化對象中狀態數據是否不相等
作用:啟動更新優化的作用,常常在高頻事件中使用。(類似節流作用)
第三個階段 組件即將更新
componentWillUpdate方法:
- 第一個參數表示
新的
屬性數據 - 第二個參數表示
新的
狀態數據
組件實例化對象上的是舊的屬性數據
組件實例化對象上的是舊的狀態數據
說明此時數據仍然沒有更新,當該方法執行完畢,數據才會更新
作用:更新插件,預處理數據等等,
註意:不要在第二個階段和第三個階段去更新屬性數據以及裝填數據
第四個階段 組件渲染視圖
render 方法
沒有參數,但是此時數據已經更新瞭
- 組件實例化對象上的是
新的
屬性數據 - 組件實例化對象上的是
新的
狀態數據
所以我們在渲染虛擬DOM的時候,可以使用這些新的數據瞭
此時虛擬DOM還沒有更新,方法執行完畢,虛擬DOM才更新
第五個階段 組件更新完成
componentDidUpdate方法:
- 第一個參數是舊的屬性數據
- 第二個參數是舊的狀態數據
組件實例化對象上的是新的
屬性數據
組件實例化對象上的是新的
狀態數據
此時虛擬DOM也已經更新完成瞭
組件更新完成瞭,我們可以在這個階段發送請求,處理事件等等,該方法執行完畢,並沒有說明存在期的結束,存在期仍然繼續,隻是一次更新的結束,所有組件生命周期方法this都指向組件實例化對象
// 定義組件 class GoTop extends Component { // 構造函數 constructor(props) { super(props); this.state = { text: props.text } } // 存在期五個階段 // 1 組件即將接收新的屬性數據 componentWillReceiveProps(newProps) { console.log(111, 'componentWillRecieveProps', newProps, this.props) // 將屬性數據,存儲到狀態中 this.setState({ text: newProps.text }) } // 2 組件是否更新 shouldComponentUpdate(newProps, newState) { console.log(222, 'shouldComponentUpdate', newProps, this.props, 'state', newState, this.state) // 是否可以更新 // return true; // 根據屬性或者狀態的改變來優化 return newProps.text !== this.props.text || newState.text !== this.state.text } // 3 組件即將更新 componentWillUpdate(newProps, newState) { console.log(333, 'componentWillUpdate', newProps, this.props, 'state', newState, this.state, findDOMNode(this).innerHTML) } // 4 渲染虛擬DOM render() { console.log(444, 'render', this.props, 'state', this.state) // return <span>{this.props.text}</span> return <span>{this.state.text}</span> } // 5 組件更新完成 componentDidUpdate(oldProps, oldState) { console.log(555, 'componentDidUpdate', oldProps, this.props, 'state', oldState, this.state, findDOMNode(this).innerHTML) } // 組件創建完成 componentDidMount() { window.onscroll = () => { // 移動超過300顯示返回頂部 if (window.scrollY > 300) { this.setState({ text: '返回頂部' }) } else { // 顯示頭條新聞 this.setState({ text: '頭條新聞' }) } // console.log(window.scrollY) } } }
到此這篇關於React中父子組件通信詳解的文章就介紹到這瞭,更多相關React組件通信內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!