组件通讯-概念
组件状态是独立的,组件化之后涉及状态同步,需要进行组件通讯
组件的特点
- 组件是
独立且封闭
的单元,默认情况下,只能使用组件自己的数据 - 在组件化过程中,通常会将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能
组件通讯意义
- 而在这个过程中,多个组件之间不可避免的要
共享
某些数据 - 为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通
- 这个过程就是组件通讯
props 基本使用
传递数据和接收数据的过程
- 使用组件的时候通过属性绑定数据,在组件内部通过 props 获取即可。
函数组件使用 props
1 2
| // 使用组件 <Hello name="jack" age="20" />
|
1 2 3 4
| function Hello(props) { return <div>接收到数据:{props.name}</div>; }
|
类组件使用 props
1 2
| // 使用组件 <Hello name="jack" age="20" />
|
1 2 3 4 5 6
| class Hello extends Component { render() { return <div>接收到的数据:{this.props.age}</div>; } }
|
props 注意事项
什么是单向数据流
- 单向数据流,是从上到下的,
自顶而下
的,数据流。 - 好比:河流,瀑布,只能从上往下流动,上游污染下游受影响,但是下游不能影响上游。
- 父组件传递数据给子组件,父组件更新数据子组件自动接收更新后数据,但是子组件是不能修改数据的。
props 可以传递什么数据?
父传子方式
大致步骤:
- 父组件提供要传递的 state 数据
- 给子组件标签添加属性,值为 state 中的数据
- 子组件中通过 props 接收父组件中传递的数据
父组件提供要传递的 state 数据
1 2 3 4 5 6 7 8 9 10 11 12
| class Parent extends React.Component { state = { money: 10000, }; render() { return ( <div> <h1>父组件:{this.state.money}</h1> </div> ); } }
|
给子组件标签添加属性,值为 state 中的数据
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Parent extends React.Component { state = { money: 10000 } render() { return ( <div> <h1>父组件:{this.state.money}</h1> + <Child money={this.state.money} /> </div> ) } }
|
子组件中通过 props 接收父组件中传递的数据
1 2 3 4 5 6 7
| function Child(props) { return ( <div> <h3>子组件:{props.money}</h3> </div> ); }
|
子传父方式
- 父组件提供回调函数,通过 props 传递给子组件
- 子组件调用 props 中的回调函数,函数可传参
- 父组件函数的参数就是子组件传递的数据
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Parent extends React.Component { state = { money: 10000, }; buyPhone = (price) => { this.setState({ money: this.state.money - price, }); }; render() { const { money } = this.state; return ( <div> <h1>父组件:{money}</h1> <Child money={money} buyPhone={this.buyPhone} /> </div> ); } }
|
子组件
1 2 3 4 5 6 7 8 9 10 11 12
| const Child = (props) => { const handleClick = () => { props.buyPhone(5000); }; return ( <div> <h3>子组件:{props.money}</h3> <button onClick={handleClick}>买手机</button> </div> ); };
|
兄弟组件通讯
通过状态提升思想完成兄弟组件数据通讯
状态提升思想是什么?
- 将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态和修改状态的方法
- 需要通讯的组件通过 props 接收状态和函数即可

参考代码:
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React, { Component } from 'react'; import ReactDOM from 'react-dom';
import Jack from './Jack'; import Rose from './Rose';
class App extends Component { state = { msg: '', }; changeMsg = (msg) => { this.setState({ msg }); }; render() { return ( <div> <h1>我是App组件</h1> {/* 兄弟组件 1 */} <Jack changeMsg={this.changeMsg}></Jack> {} <Rose msg={this.state.msg}></Rose> </div> ); } } // 渲染组件 ReactDOM.render(<App />, document.getElementById('root'));
|
Jack.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import React, { Component } from 'react';
export default class Jack extends Component { say = () => { this.props.changeMsg('you jump i look'); }; render() { return ( <div> <h3>我是Jack组件</h3> <button onClick={this.say}>说</button> </div> ); } }
|
Rose.jsx
1 2 3 4 5 6 7 8 9 10 11
| import React, { Component } from 'react';
export default class Rose extends Component { render() { return ( <div> <h3>我是Rose组件-{this.props.msg}</h3> </div> ); } }
|
context 跨级组件通讯
什么是跨级组件通讯?
context 怎么去理解?
- 术语:上下文
- 理解:一个范围,只要在这个范围内,就可以跨级组件通讯。(不需要 props 层层传递)

context 使用方法
context.js
1 2
| import { createContext } from 'react' export default createContext(初始值)
|
1 2 3 4 5 6 7 8 9 10 11
| import Context from './context' import Child from './Child';
function Parent () { return ( <Context.Provider value={context共享的值}> ....子孙组件 </Context.Provider> ) }
|
1 2 3 4 5 6 7 8 9 10
| import Context from './context' function Child () { return ( <Context.Consumer> { value => JSX } </Context.Consumer> ) }
|
index.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import React, { Component, createContext } from 'react' import Parent from './Parent'
export const MyContext = createContext() export default class App extends Component { state = { money: 10000 } updateMoney = newMoney => { this.setState({ money: newMoney }) } render() { return ( <MyContext.Provider value={{ money: this.state.money, updateMoney: this.updateMoney }}> <div className="app"> <h1>根组件:{this.state.money}</h1> <hr /> <Parent /> </div> </MyContext.Provider> ) } }
|
Parent.jsx
1 2 3 4 5 6 7 8 9 10 11 12
| import Child from './Child'; const Parent = () => { return ( <div className="parent"> <h3>父组件:</h3> <hr /> <Child /> </div> ); }; export default Parent;
|
Child.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import { MyContext } from './App' const Child = () => { return ( <MyContext.Consumer> {(value) => ( <div className="child"> <h5>子组件:{value.money} <button onClick={()=>value.updateMoney(5000)}>修改money</button></h5> </div> )} </MyContext.Consumer> ); }; export default Child;
|
总结:
- 使用
creatContext()
创建一个上下文对象,包含:Provider
Consumer
组件。 - 使用
Provider
包裹组件,value
属性注入状态,函数
,被包裹组件下的任何组件可以使用。 - 使用
Consumer
消费 Provider
提供的数据和函数,语法{value=>使用数据和函数}