React的组件之间互相传值
- 父子组件传值
- 兄弟组件传值
- 上下文context
父子组件传值
react 中父组件可以将数据作为子组件的属性进行传值,子组件通过 props 属性接收值。
父组件可以监听子组件中的某个事件,子组件直接在内部触发 props 事件即可以触发父组件监听的事件,由此父组件可以进行响应。
//父组件 App
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "我是有关于App父组件组件的标题"
}
}
//定义getMsg方法 让子组件调用 con是子组件传过来的值
getMsg = (con) => {
console.log(con);
this.setState({ title: con })
}
render() {
return (
<div className="App">
{/*父组件向子组件 传值*/}
<Goods title="给Goods组件传的值" />
{/*父组件定义一个方法 通过子组件调用 顺便可以拿到子组件传过来的值*/}
<h3>{this.state.title}</h3>
<Goods fn1={this.getMsg} />
</div>
);
}
}
export default App;
//子组件 Goods
class Goods extends Component {
constructor(props) {
super(props)
}
//通过触发add方法
add() {
this.props.fn1("我是由子组件Goods 传值给 父组件App 修改父组件中的title值")
}
render() {
return (
<div>
{/*在此处可以使用 this.props.title拿到父组件传过来的值*/}
<h3>{this.props.title}</h3>
{/*这里定义一个按钮 通过点击事件来触发 绑定在父组件中的方法fn1*/}
<input type="button" value='提交' onClick={this.add.bind(this)} />
</div>
);
}
}
Goods.propTypes = { //指定接收数据的类型 isRequired意思是必填的
"title": PropTypes.string.isRequired
};
Goods.defaultProps = { //属性的默认值
"title": "我是子传父goods默认值"
};
export default Goods;
兄弟组件传值
兄弟组件之间的传值,是通过父组件做的中转 ,流程为:
组件A – 传值 --> 父组件 – 传值 --> 组件B
其实可以理解为把前两个步骤又重新做了一遍,即先执行子组件传值父组件,然后再执行父组件传值子组件。但是这样的话会很繁琐! 我们可以定义一个新的js文件,通过引入这个EventEmitter方法进行创建一个仓库,来定义emit on 方法进行传值!
// 引入EventEmitter 方法 可以理解为一个仓库
import { EventEmitter } from 'events';
export default new EventEmitter();
import eventbus from '../lib/eventbus'
//兄弟组件1 Com_one
class Com_one extends Component {
constructor(props) {
super();
this.state = {
}
}
//兄弟组件传值 触发emit()方法
push() {
eventbus.emit('abc', "这是Com_one向Com_two组件传的值")
}
render() {
return (
<div>
{/* 兄弟组件传值 */}
<input type="button" value="传值" onClick={this.push.bind(this)} />
</div>
);
}
}
export default Com_one;
import eventbus from '../lib/eventbus'
//兄弟组件2 Com_two
class Com_two extends Component {
constructor(props) {
super(props);
this.state = {
result: "这是com_two组件默认值"
}
}
//生命周期函数 首先运行 兄弟组件传值接收Com_one值
componentDidMount() {
eventbus.on('abc', (msg) => {
this.setState({ result: msg })
})
}
render() {
return (
<div>
<h3>{this.state.result}</h3>
</div>
);
}
}
export default Com_two;
上下文context
-
Context上下文
Context 通过组件树提供了一个传递数据的方法,从而避免了在每一个层级手动的传递 props 属性。 它是一个从上向下传递的方式。
-
如何使用
步骤 1. 通过createContext创建Context 2. 使用Context.Provider组件发布数据(通过给Context.Provider传递value属性)。 3. Context.Provider的所有后代组件,都可以通过Context.Consumer消费数据
//引入 createContext 创建Context
import { createContext } from "react"
var c = createContext()
export default c
//App 父组件
import UseContext from '../context'
function App() {
var one = { one: '我是传递给层层传递的数据,每层都能接收到' }
return (
<div className="App">
{/* 通过value属性指定要层层传递的值 以发送者的身份*/}
{/* 如果Provider没有传入value属性,默认会将value设置为undefined */}
<UseContext.Provider value={one}>
/*里面可以渲染对应的内容*/
<Hello />
</UseContext.Provider>
</div>
);
}
export default App;
//App 下的子组件 Hello下的子组件也能以这种方式获取到值
import UserContext from '../context'
class Hello extends Component {
state = {
num: 20
}
render() {
return (
<div className='hello'>
{/* 订阅数据 以接收者的身份*/}
<UserContext.Consumer>
{
context => (
<h2>{context.one}</h2>
)
}
</UserContext.Consumer>
</div>
);
}
}
export default Hello;