# 组件通讯
多组件之间共享通讯
## props接收传递给组件的数据
传递数据:给组件标签添加属性
函数组件 props
```html
const HelloProps = (props)=>{
console.log(props)
return (
props:{props.name}
)
}
ReactDOM.render(,document.getElementById('root'))
```
类组件 this.props
```html
class HelloProps extends React.Component{
render(){
return (props:{this.props.name},{this.props.role}
)
}
}
ReactDOM.render(,document.getElementById('root'))
```
## 组件特点
1. 可以是任意值
```html
class HelloProps extends React.Component{
render(){
console.log(this.props)
return (props:{this.props.name},{this.props.role} {this.props.tag}
)
}
}
ReactDOM.render(console.log('我可以传函数')}
tag={jsx
}
/>,document.getElementById('root'))
```
2. 只读
3. 在使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中获取到props
```html
class HelloProps extends React.Component{
constructor(props){
super(props)
console.log(this.props)
}
render(){
console.log(this.props)
return (props:{this.props.name},{this.props.role} {this.props.tag}
)
}
}
ReactDOM.render(console.log('我可以传函数')}
tag={jsx
}
/>,document.getElementById('root'))
```
## 通讯的三种方式
### 父组件传递给子组件
1. 父组件提供传递的state数据
2. 给子组件添加属性,值为state中的数据
3. 子组件中通过props接收父组件中传递的数据
```html
class Parent extends React.Component{
state = {lastName:'师'}
render(){
return (
父组件:
)
}
}
// 子组件
const Child = (props)=>{
return (
子组件接收到父组件的数据 {props.name}
)
}
ReactDOM.render(,document.getElementById('root'))
```
### 子组件传递给父组件
利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数.
1. 父组件提供一个回调函数(用于接收数据)
2. 将改函数作为属性的值,传递给子组件
3. 子组件通过props调用回调函数
4. 将子组件的数据作为参数传递给回调函数
```html
class Parent extends React.Component{
state={
parentMsg:''
}
getChildMsg = data=>{
console.log('接收到子组件传递过来的数据',data)
this.setState({
parentMsg:data
})
}
render(){
return (
父组件:{this.state.parentMsg}
)
}
}
// 子组件
class Child extends React.Component{
state = {
msg:"回调传递"
}
handleClick=()=>{
//
this.props.name(this.state.msg)
}
render(){
return (
)
}
}
ReactDOM.render(,document.getElementById('root'))
```
## 兄弟组件间的通讯
将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态
状态提升
公共父组件职责:1.提供共享状态2.提供操作共享状态的方法
要通讯的子组件只能通过props接收状态或者操作状态的方法
```html
class Counter extends React.Component{
state={
count:0
}
onIncrement=()=>{
this.setState({
count:this.state.count+1
})
}
render(){
return(
)
}
}
const Child1=(props)=>{
return 计数器:{props.count}
}
const Child2=(props)=>{
return
}
ReactDOM.render(,document.getElementById('root'))
```
# Context跨组件传递数据
1. 使用React.createContext()创建Provider,Consumer
2. 使用Provide组件作为父节点
3. 设置value属性,表示要传递的数据
4. 调用Consumer组件来接收数据
```html
const { Provider, Consumer } = React.createContext();
class ContextApp extends React.Component {
render() {
return (
)
}
}
const Node = props => {
return (
)
}
const SubNode = props => {
return (
)
}
const Child = props => {
return {data=>我是子节点---{data}}
}
```
# props深入
## children表示组件标签的子节点.当组件标签有子节点时,props就会有该属性.
children 属性与普通props一样,值可以是任意值(文本,React元素,组件,甚至是函数)
```html
class ChildProps extends React.Component{
render(){
console.log(this.props)
return (
组件标签的子节点{this.props.children}
)
}
}
ReactDOM.render(传递到props的child,document.getElementById('root'))
```
```html
class ChildProps extends React.Component{
render(){
console.log(this.props)
return (
组件标签的子节点
{this.props.children}
)
}
}
const Test = ()=>
ReactDOM.render(传递到props的child
,document.getElementById('root'))
```
函数
```html
class ChildProps extends React.Component{
render(){
this.props.children()
console.log(this.props)
return (
组件标签的子节点
)
}
}
ReactDOM.render({()=>console.info("这是一个函数")},document.getElementById('root'))
```
## prop 校验
1. 安装prop-types (npm i prop-types 或者 yarn add prop-types)
2. 导入prop-types包
3. 使用组件名.propTypes={}来给组件的props添加校验规则
4. 校验规则通过PropTypes对象指定
```html
import React from "react"
import PropTypes from "prop-types"
class PropCheck extends React.Component{
render(){
const arr = this.props.colors
console.info(arr)
const lis = arr.map((item,index)=>{item})
return (
)
}
}
PropCheck.protoTypes= {
colors:PropTypes.array
}
export default PropCheck
ReactDOM.render(,document.getElementById('root'))
```
## prop 默认值
```html
class LPropCheck extends React.Component{
render(){
// const arr = this.props.colors
// console.info(arr)
// const lis = arr.map((item,index)=>{item})
// return (
//
// )
return test
{this.props.colors}
}
}
LPropCheck.propTypes= {
colors:PropTypes.array
}
LPropCheck.defaultProps= {
colors:["red"]
}
```