父传子
类组件父传子
看似是父类super(props)做了保存,实际上转为es5是子组件自己做的保存
函数组件父传子
参数propTypes类型验证
对于父组件传递给子组件的数据,我们希望对数据类型验证,或者进行限制,使用propTypes库
从 React v15.5 开始,React.PropTypes 已移入另一个包中:prop-types 库
对于特别复杂的验证,推荐ts
源码相关
子传父
传值应用:react实现slot
我们发现vue有一个非常好用的功能,slot插槽。react没有,因为react更灵活,完全不需要,jsx语法可以向变量一样传递给子组件
方法一:this.props.children(不推荐,需要顺序,一个值时可以使用)
源码相关
方法二:把jsx作为变量传递给子组件(推荐,可具名传递)
context跨组件通信
相关API
基本使用
import React, { Component } from 'react'
/* 第一步创建一个context对象,可以给默认值 */
const MyContext = React.createContext({name:"zhao",age:18})
class Header extends Component{
render() {
return(
<div>
<span>name:{this.context.name}</span>
<span>age:{this.context.age}</span>
</div>
)
}
}
/* 第三步,子孙组件宣布使用 */
Header.contextType = MyContext
function Main() {
return(
<div>
<Header/>
<ul>
<li>xxxx</li>
<li>xxxx</li>
</ul>
</div>
)
}
/* 第二步,在父组件中对子孙组件包裹,value中指定给子孙组件的值 */
export default class App extends Component {
constructor(props) {
super(props)
this.state={
name:"why",
age:30
}
}
render() {
return (
<div>
<MyContext.Provider value={{...this.state}}>
<Main/>
</MyContext.Provider>
</div>
)
}
}
什么时候使用默认值defaultValue呢
当子孙组件没有被context.provider包裹时,子孙组件又订阅了context
什么时候使用Context.Consumer呢
1.当使用value的组件是一个函数式组件时;
2.当组件中需要使用多个Context时;(嵌套,太恶心了,不想写)
后面多个组件我们使用redux,这个了解就好
事件总线events
import React, { PureComponent } from 'react'
/* 第一步安装yarn add events 导入 导入的是一个类 */
import {EventEmitter} from 'events'
/* 第二步 创建一个 全局事件总线对象 */
const eventBus = new EventEmitter()
export default class App extends PureComponent {
render() {
return (
<div>
<Home></Home>
<Goods></Goods>
</div>
)
}
}
class Home extends PureComponent{
render(){
return(
<div>
<h2>Home</h2>
<button onClick={e=>{this.onClickBtn()}}>发射事件</button>
</div>
)
}
onClickBtn(){
/*第三步 发射事件 第一个参数事件名称,第二个可以为多个参数 放到伪数组args中*/
eventBus.emit('sayHello','why',18)
}
}
class Goods extends PureComponent{
constructor(){
super()
this.state = {
name:"zhao",
age:22
}
}
render(){
return(
<div>
<h2>Goods</h2>
<p>{this.state.name}{this.state.age}</p>
</div>
)
}
/* 第四步 在生命周期函数中监听 第一个参数要监听事件名称,第二个是回调函数 */
componentDidMount(){
eventBus.addListener('sayHello',(name,age)=>{
this.setState({
name:name,
age:age
})
})
}
/* 不要忘了移除事件监听 */
componentWillUnmount(){
eventBus.removeListener('sayHello',(name,age)=>{
console.log(name,age);
})
}
}