React组件通信-父子组件间的通信
文章目錄
- React父子組件通信
- 認(rèn)識(shí)組件嵌套
- 組件通信
- 父?jìng)髯?/li>
- 參數(shù)驗(yàn)證
- 子傳父
React父子組件通信
認(rèn)識(shí)組件嵌套
組件之間存在嵌套關(guān)系:
在之前的案例中,我們只是創(chuàng)建了一個(gè)組件App;
如果我們一個(gè)應(yīng)用程序?qū)⑺械倪壿嫸挤旁谝粋€(gè)組件中,那么這個(gè)組件就會(huì)變成非常的臃腫和難以維護(hù);
所以組件化的核心思想應(yīng)該是對(duì)組件進(jìn)行拆分,拆分成一個(gè)個(gè)小的組件;
再將這些組件組合嵌套在一起,最終形成我們的應(yīng)用程序;
上面的嵌套邏輯如下,它們存在如下關(guān)系:
App組件是Header、Main、Footer組件的父組件;
import React, { Component } from 'react'import Header from './Header' import Main from "./Main" import Footer from './Footer'export class App extends Component {render() {return (<div><Header/><Main/><Footer/></div>)} }export default AppMain組件是Banner、ProductList組件的父組件
import React, { Component } from 'react' import Banner from './Banner' import ProductList from './ProductList'export class Main extends Component {render() {return (<div><div>Main</div><Banner/><ProductList/></div>)} }export default Main組件通信
在開(kāi)發(fā)過(guò)程中,我們會(huì)經(jīng)常遇到需要組件之間相互進(jìn)行通信:
比如App可能使用了多個(gè)Header,每個(gè)地方的Header展示的內(nèi)容不同,那么我們就需要使用者傳遞給Header一些數(shù)據(jù),讓其進(jìn)行展示;
又比如我們?cè)贛ain中一次性請(qǐng)求了Banner數(shù)據(jù)和ProductList數(shù)據(jù),那么就需要傳遞給他們來(lái)進(jìn)行展示;
也可能是子組件中發(fā)生了事件,需要由父組件來(lái)完成某些操作,那就需要子組件向父組件傳遞事件;
總之,在一個(gè)React項(xiàng)目中,組件之間的通信是非常重要的環(huán)節(jié);
父?jìng)髯?/h4>
父組件在展示子組件時(shí),可能會(huì)傳遞一些數(shù)據(jù)給子組件:
父組件通過(guò) 屬性=值的形式來(lái)傳遞給子組件數(shù)據(jù);
子組件通過(guò) this.props 獲取父組件傳遞過(guò)來(lái)的數(shù)據(jù);
例如我們來(lái)看這樣一個(gè)需求, 父組件將定義的數(shù)組books傳遞給子組件, 由子組件進(jìn)行展示
將數(shù)組傳遞給子組件
export class App extends Component {constructor() {super()this.state = {books: [{name: "算法導(dǎo)論", price: 79},{name: "數(shù)據(jù)結(jié)構(gòu)", price: 69},{name: "漫畫(huà)算法", price: 59},]}}render() {const { books } = this.statereturn (<div>{/* 將數(shù)據(jù)傳遞給子組件 */}<Header books={books}/></div>)} }在子組件接受父組件傳遞的數(shù)據(jù)
export class Header extends Component {render() {// 接受父組件傳遞過(guò)來(lái)的參數(shù)const { books } = this.propsreturn (<div><ul>{books.map(item => {return (<li key={item.name}>名稱: {item.name} 價(jià)格: {item.price}</li>)})}</ul></div>)} }參數(shù)驗(yàn)證
對(duì)于傳遞給子組件的數(shù)據(jù),有時(shí)候我們可能希望進(jìn)行驗(yàn)證,特別是對(duì)于大型項(xiàng)目來(lái)說(shuō):
當(dāng)然,如果你項(xiàng)目中默認(rèn)繼承了Flow或者TypeScript,那么直接就可以進(jìn)行類型驗(yàn)證;
但是,即使我們沒(méi)有使用Flow或者TypeScript,也可以通過(guò) prop-types 庫(kù)來(lái)進(jìn)行參數(shù)驗(yàn)證;
從 React v15.5 開(kāi)始,React.PropTypes 已移入另一個(gè)包中:prop-types 庫(kù)
使用方法, 先在子組件中導(dǎo)入PropTypes, 再對(duì)傳遞過(guò)來(lái)的元素添加類型限制即可
import React, { Component } from 'react'// 導(dǎo)入PropTypes import PropTypes from 'prop-types'export class Header extends Component {render() {const { books, name, age } = this.propsreturn (<div><div>名字: {name} 年齡: {age}</div><ul>{books.map(item => {return (<li key={item.name}>名稱: {item.name} 價(jià)格: {item.price}</li>)})}</ul></div>)} }// 對(duì)參數(shù)添加類型的限制 Header.propTypes = {// 表示傳入的類型是要求一個(gè)數(shù)組, 并且必傳books: PropTypes.array.isRequired,// 傳入類型string, 非必傳name: PropTypes.string,// 傳入類型number, 非必傳age: PropTypes.number }export default Header更多的驗(yàn)證方式,可以參考官網(wǎng):https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html
比如驗(yàn)證數(shù)組,并且數(shù)組中包含哪些元素;
比如驗(yàn)證對(duì)象,并且對(duì)象中包含哪些key以及value是什么類型;
比如某個(gè)原生是必須的,使用 requiredFunc: PropTypes.func.isRequired
如果沒(méi)有傳遞,我們希望有默認(rèn)值呢?
我們使用defaultProps就可以了
Header.defaultProps = {name: "默認(rèn)名稱" }子傳父
某些情況,我們也需要子組件向父組件傳遞消息:
在vue中是通過(guò)自定義事件來(lái)完成的;
在React中同樣是通過(guò)props傳遞消息,只是讓父組件給子組件傳遞一個(gè)回調(diào)函數(shù),在子組件中調(diào)用這個(gè)函數(shù)即可;
我們這里來(lái)完成一個(gè)案例:
將計(jì)數(shù)器案例進(jìn)行拆解;
將按鈕封裝到子組件中:CounterButton;
CounterButton發(fā)生點(diǎn)擊事件,將內(nèi)容傳遞到父組件中,修改counter的值;
演示代碼
父組件傳遞一個(gè)事件給子組件CounterButton
import React, { Component } from 'react' import ConterButton from './c-cpn/ConterButton'export class App extends Component {constructor() {super()this.state = {conter: 100}}changeConter(conter) {this.setState({ conter: this.state.conter + conter })}render() {const { conter } = this.statereturn (<div><h2>{conter}</h2>{/* 向子組件中傳入一個(gè)事件 */}<ConterButton getConter={conter => this.changeConter(conter)}/></div>)} }export default App子組件在按鈕發(fā)生點(diǎn)擊時(shí), 對(duì)父組件的傳遞的函數(shù)進(jìn)行回調(diào), 并傳入一個(gè)參數(shù)出去
import React, { Component } from 'react'export class ConterButton extends Component {btnClick(conter) {// 當(dāng)按鈕發(fā)生點(diǎn)擊事件時(shí), 對(duì)父組件傳遞過(guò)來(lái)的函數(shù)進(jìn)行回調(diào)this.props.getConter(conter)}render() {return (<div><button onClick={() => this.btnClick(-1)}>-1</button><button onClick={() => this.btnClick(1)}>+1</button></div>)} }export default ConterButton總結(jié)
以上是生活随笔為你收集整理的React组件通信-父子组件间的通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Cocoa
- 下一篇: 网络正常且开启了代理Chrome不能正常