父传子
父组件通过自定义属性传值给子组件, 子组件内部通过props获取值
//父
class App extends Component {
saveMoney(m){
console.log(m);
}
render() {
return (
<div className='app'>
<Child title="3天学完react!"/>
</div>
);
}
}
//子
class Child extends Component {
render() {
return (
<div className='child'>
<h1> { this.props.title } </h1>
子组件
</div>
);
}
}
子传父
父组件通过自定义属性传一个函数给子组件, 子组件内部通过props获取该函数并在合适的时机回调该函数完成传值.
(相当于父亲给儿子留下电话号码,在儿子有需求的时候打给父亲,然后让父亲来做一些事)
//父
class App extends Component {
saveMoney(m){
console.log(m);
}
render() {
return (
<div className='app'>
<Child saveMoney={this.saveMoney} />
</div>
);
}
}
//子
class Child extends Component {
render() {
return (
<div className='child'>
<button onClick={()=>{ this.props.saveMoney(100) }}>点击传值</button>
子组件
</div>
);
}
}
兄弟组件传值
借助events库 先实例化一个公共的通信对象, 其中一个组件提前监听事件, 另一个兄弟组件在合适的时机触发事件并传值.
(一般在utils文件下创建一个eventBus作为通信桥梁
,与vue中中央事件总线同理)
import { EventEmitter } from 'events' //实例化一个公共通信对象 export default new EventEmitter();
//首先得有兄弟关系
class App extends Component {
render() {
return (
<div className='app'>
<ChildA />
<ChildB />
</div>
);
}
}
//A
//导入公共的通信对象实例
import eventBus from '../utils/eventBus'
class ChildA extends Component {
handleClick(){
//触发事件并传值
eventBus.emit('msg',88888);
}
render() {
return (
<div className='childA'>
我是ChildA组件 <button onClick={()=>{ this.handleClick() }}>传值</button>
</div>
);
}
}
//B
//导入公共的通信对象实例
import eventBus from '../utils/eventBus'
class ChildB extends Component {
handleMSG = (data)=>{
console.log('ChildB:', data);
}
componentDidMount(){
//监听事件
eventBus.on('msg', this.handleMSG )
}
componentWillUnmount(){
//取消监听
eventBus.off('msg', this.handleMSG )
}
render() {
return (
<div className='childb'>
我是ChildB组件
</div>
);
}
}
跨组件传值
借助createContext方法 先实例化一个公共的上下文通信对象, 外层组件通过Provider组件的value属性传值, 内层组件和上下文通信对象建立连接, 然后再通过this.context获取值.
(一般在utils文件下创建一个context作为通信桥梁)
import React from 'react' //实例化一个功能的通信上下文对象 export default React.createContext()
(实际开发基本不用,但是面试官会问)
//父
class App extends Component {
render() {
return (
<div className='app'>
<context.Provider value={66666}>//通过value传值
<ChildC />
</context.Provider>
</div>
);
}
}
//子
class ChildC extends Component {
render() {
return (
<div className='childC'>
我是ChildC组件
<ChildD />
</div>
);
}
}
//孙
//导入公共的上下文通信对象
import context from '../utils/context';
class ChildD extends Component {
render() {
return (
<div className='childD'>
我是ChildD组件 - { this.context }
</div>
);
}
}
//和通信对象建立连接
ChildD.contextType = context;
小面
相同点:都是对象,都是用来存储数据
不同点:props用来接收父组件传来的值,默认是只读的.
state用来定义组件自身的状态,可以通过setstate来修改.|
props中只要传过来的是引用数据类型,那就说明是地址,就可以改里面的数据