react笔记(六)—— 组件通讯子传父
前言
大家好呀,我是L同学。在上篇文章react笔记(五)—— 组件通讯父传子中,我们学习了组件通信、props基本使用、props注意点、父传子等相关知识点。在这篇文章中,我们将学习到组件通讯子传父、兄弟组件组件通讯、使用context实现跨级组件通讯、props校验等相关知识点。
组件通讯——子传父
子组件的数据传递给父组件,利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数。 父组件提供一个回调函数(用于接收数据)(箭头函数)。将该函数作为属性的值,传递给子组件。子组件通过 props 调用回调函数。将子组件的数据作为参数传递给回调函数。
父组件提供函数并且传递给子组件。
class Parent extends React.Component {
getChildMsg = (msg) => {
console.log('接收到子组件数据', msg)
}
render() {
return (
<div>
子组件:<Child getMsg={this.getChildMsg} />
</div>
)
}
}
子组件接收函数并且调用。
class Child extends React.Component {
state = { childMsg: 'React' }
handleClick = () => {
this.props.getMsg(this.state.childMsg)
}
return (
<button onClick={this.handleClick}>点我,给父组件传递数据</button>
)
}
组件通讯——兄弟组件
状态提升可以实现兄弟组件之间的组件通讯。将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态。思想是状态提升。公共父组件职责是提供共享状态,提供操作共享状态的方法。要通讯的子组件只需通过 props 接收状态或操作状态的方法。
index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Jack from './Jack'
import Rose from './Rose'
class App extends Component {
// 1. 状态提升到父组件
state = {
msg: '',
}
render() {
return (
<div>
<h1>我是App组件</h1>
<Jack say={this.changeMsg}></Jack>
{/* 2. 把状态给子组件显示 */}
<Rose msg={this.state.msg}></Rose>
</div>
)
}
changeMsg = (msg) => {
this.setState({
msg,
})
}
}
// 渲染组件
ReactDOM.render(<App />, document.getElementById('root'))
jack.js
import React, { Component } from 'react'
export default class Jack extends Component {
render() {
return (
<div>
<h3>我是Jack组件</h3>
<button onClick={this.say}>说</button>
</div>
)
}
say = () => {
this.props.say('you jump i look')
}
}
rose.js
import React, { Component } from 'react'
export default class Rose extends Component {
render() {
return (
<div>
<h3>我是Rose组件-{this.props.msg}</h3>
</div>
)
}
}
组件通讯 - Context
通过context可以实现跨级组件通讯。组件之间的层级关系,除了以上两种常见的情况外,还有一种不太常见的情况,那就是:远房亲戚关系(也就是两个组件之间间隔较远)。实现方式是使用 Context 来实现跨组件传递数据。
import { createContext } from 'react'
// 1 创建 Context 对象
const { Provider, Consumer } = createContext()
// 2 使用 Provider 组件包裹整个应用,并通过 value 属性提供要共享的数据
<Provider value="blue">
<div className="App">
<Child1 />
</div>
</Provider>
// 3 使用 Consumer 组件接收要共享的数据
<Consumer>
{data => <span>data参数表示接收到的数据 -- {data}</span>}
</Consumer>
props中children属性
children属性表示该组件的子节点,只要组件有子节点,props就有该属性。children 属性与普通的props一样,值可以是任意值(文本、React元素、组件,甚至是函数)。
function Hello(props) {
return (
<div>
该组件的子节点:{props.children}
</div>
)
}
<Hello>我是子节点</Hello>
props校验
props校验接收的props的数据类型,增加组件的健壮性。对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据。如果传入的数据格式不对,可能会导致组件内部报错。组件的使用者不能很明确的知道错误的原因。props校验允许在创建组件的时候,就约定props的格式、类型等。
使用步骤:
- 导入
prop-types
包 - 使用
组件名.propTypes = {}
来给组件的props添加校验规则 - 校验规则通过
PropTypes
对象来指定
import PropTypes from 'prop-types'
function App(props) {
return (
<h1>Hi, {props.colors}</h1>
)
}
App.propTypes = {
// 约定colors属性为array类型
// 如果类型不对,则报出明确错误,便于分析错误原因
colors: PropTypes.array
}
props校验-规则
react组件props校验的常见规则:
常见类型:array、bool、func、number、object、string
React元素类型:element
必填项:isRequired
特定结构的对象:shape({})
// 常见类型
optionalFunc: PropTypes.func,
// 必选
requiredFunc: PropTypes.func.isRequired,
// 特定结构的对象
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
})
转载自:https://juejin.cn/post/7128033802890248205