父子通信
父组件在展示子组件的时候,可能会传递一些数据给子组件
- 父组件通过 属性=值 的形式来传递给子组件数据
- 子组件通过 props 参数获取父组件传递过来的数据
父传子
父组件
js
<MainBanner banners={banners}/}子组件
js
class MainBanner extends Component {
constructor(props) {
super(props)
}
render() {
const {banners} = this.props
}
}传递之后还相当于在constructor(){}做了一个this.props = props
并且如果不需要写this.state的话,其实整个constructor(){}都可以不写了,系统会默认帮你做这个操作
案例
父组件App.js
jsx
import { Component } from 'react'
import Header from 'components/Header'
import Banner from 'components/Banner'
import Footer from 'components/Footer'
export class App extends Component {
constructor() {
super()
this.state = {
bannerList: ["花束般的恋爱", "花样年华", "爱乐之城"]
}
}
render() {
let { bannerList } = this.state
return (
<div>
<Header />
<Banner bannerList = {bannerList}/>
<Footer />
</div>
)
}
}
export default App子组件Banner.jsx
jsx
import React, { Component } from 'react'
export class Banner extends Component {
render() {
let { bannerList } = this.props
return (
<div>
<ul>
{bannerList.map(item => <li key={item}>{item}</li>)}
</ul>
</div>
)
}
}
export default Banner参数propTypes(类型校验)
对于传递给子组件的数据,有时候我们可能希望进行验证,特别是对于大型项目来说
- 当然,如果你项目中默认继承了flow或者typescript,那么直接就可以进行类型验证
- 但是,即使我们没有使用flow或者typescript,也可以通过prop-types库来进行参数验证
从react v15.5开始,React.PropTypes已移入另一个包中:prop-types库
比如验证数组,并且数组中包含哪些元素
比如验证对象,并且对象中包含哪些key以及value是什么类型
比如某个原生是必须的,使用requiredFunc: PropTypes.func.isRequired
如果没有传递,而我们希望有默认值
- 使用defaultProps
子组件的案例:
jsx
import { Component } from 'react'
import PropTypes from "prop-types"
export class Banner extends Component {
render() {
let { bannerList, title } = this.props
return (
<div>
<h3>{ title }</h3>
<ul>
{bannerList.map(item => <li key={item}>{item}</li>)}
</ul>
</div>
)
}
}
// Banner传入的props类型进行验证
Banner.propTypes = {
bannerList: PropTypes.array,
title: PropTypes.string
}
// Banner传入的props的默认值
Banner.defaultProps = {
bannerList: [],
title: "默认标题"
}
export default Banner子传父
- 在react中同样是通过props传递消息,只是让父组件给子组件传递一个回调函数,在子组件中调用这个函数即可
案例:
子组件
jsx
import { Component } from 'react'
export class AddCounter extends Component {
addClick(num) {
console.log("add number: ", num)
this.props.addCount(num)
}
render() {
return (
<div>
<button onClick={e => this.addClick(1)}>+1</button>
<button onClick={e => this.addClick(5)}>+5</button>
<button onClick={e => this.addClick(10)}>+10</button>
</div>
)
}
}
export default AddCounter父组件
jsx
import { Component } from 'react'
import AddCounter from './AddCounter';
export class Header extends Component {
constructor() {
super()
this.state = {
counter: 0
}
}
changeCounter(num) {
this.setState({counter: this.state.counter + num})
}
render() {
let { counter } = this.state;
return (
<div>
<h2>Header</h2>
<h3>Counter: { counter }</h3>
<AddCounter addCount={(num) => this.changeCounter(num)} />
</div>
)
}
}
export default Header