一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
前言
大家好呀,我是L同学。在上篇文章中react基础(五)— 组件定义方式和生命周期,我们学习了react中组件定义方式和生命周期。接下来,我们学习各个组件间该如何通信。
父子组件通信 —— 父传子
在开发中我们写多个组件,而组件间存在嵌套关系,并且我们经常需要在组件之间相互通信。
父组件在展示子组件的时候,可能会传递一些数据给子组件。那么父组件的数据该怎么传递给子组件呢?
- 父组件通过属性=值的方式给子组件传递数据
- 子组件通过props参数获取父组件传递过来的数据
我们来看下子组件分别为类组件和函数组件,父组件是怎么传递的。
类组件
import React, { Component } from "react";
class ChildCpn extends Component {
render() {
const {name, age, height} = this.props
return (
<h2>子组件展示数据:{name + ' ' + age + ' ' + height}</h2>
)
}
}
export default class App extends Component {
render() {
return (
<div>
<ChildCpn name="haha" age="18" height="1.88"></ChildCpn>
<ChildCpn name="xixi" age="16" height="1.98"></ChildCpn>
</div>
)
}
}
我们可以看到子组件成功获取到了父组件传递过来的数据,并进行了展示。
函数组件
import React, { Component } from 'react'
function ChildCpn(props) {
const { name, age, height } = props
return (
<h2>子组件展示数据:{name + ' ' + age + ' ' + height}</h2>
)
}
export default class App extends Component {
render() {
return (
<div>
<ChildCpn name="haha" age="18" height="1.88"></ChildCpn>
<ChildCpn name="xixi" age="16" height="1.99"></ChildCpn>
</div>
)
}
}
参数验证
对于传递给子组件的数据,有时候我们会进行验证,我们会通过prop-types库来进行参数验证。
在这个例子中我们给传递给子组件的数据做个验证。name数据是必须的,并且是字符串;age和height数据必须是Number类型;names数据必须是数组。
import React, { Component } from 'react'
import PropTypes from 'prop-types'
function ChildCpn(props) {
const { name, age, height, names } = props
return (
<div>
<h2>{name + ' ' + age + ' ' + height}</h2>
<ul>
{
names.map(item => {
return <li>{item}</li>
})
}
</ul>
</div>
)
}
ChildCpn.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
height: PropTypes.number,
names: PropTypes.array
}
export default class App extends Component {
render() {
return (
<div>
<ChildCpn name="haha" age='18' height={1.88} names={['小王', '小何', '小白']}></ChildCpn>
</div>
)
}
}
我们可以看到当父组件传递给子组件的age数据为字符串时,会报警告,期待是Number类型,但是获取到的是String类型。
那么如果父组件没有传递给子组件数据,子组件还想要使用,那么我们可以使用defaultProps指定默认值。
ChildCpn.defaultProps = {
name: 'hahahaha',
age: 20,
height: 1.89,
names: ['abc', 'cba']
}
我们来测试下。往父组件中增加一个子组件,不传递数据,会使用默认值。
<ChildCpn></ChildCpn>
我们可以看到页面上渲染的是默认值。
同样,类组件添加类型验证可以用上述方法。除了这一种,类组件还可以这样进行类型验证。
class ChildCpn2 extends Component {
// es6中的class fields写法
static propTypes = {
}
static defaultProps = {
name: 'hahahaha',
age: 20,
height: 1.89,
names: ['abc', 'cba']
}
}
第一种ChildCpn.defaultProps = {}方式相当于给类添加了静态方法。
父子组件通信 —— 子传父
除了父组件给子组件传递数据,有时候,我们还需要子组件给父组件传递数据。
在react中,子组件传递数据给父组件同样使用props,只是让父组件给子组件传递一个回调函数,在子组件中调用这个回调函数就可以。
接下里,我们做个小案例。需求是这样子的,我们把按钮封装到子组件CounterButton中,点击这个按钮,CounterButton就发生了点击事件,将内容传递到父组件,修改counter的值。
import React, {Component} from 'react'
class CounterButton extends Component {
render() {
const {onClick1} = this.props
return <button onClick={onClick1}>+1</button>
}
}
export default class App extends Component {
constructor() {
super()
this.state = {
counter: 0
}
}
render() {
return (
<div>
<h2>当前计数:{this.state.counter}</h2>
<CounterButton onClick1={() => {this.increment()}}></CounterButton>
</div>
)
}
increment() {
this.setState({
counter: this.state.counter + 1
})
}
}
我们可以看到点击子组件中的按钮,父组件中的数据发生了改变。