React的组件通信与状态管理

发布时间 2023-03-23 15:42:29作者: __fairy

目录

1. 组件通讯-概念

1.组件的特点

2.知道组件通讯意义

总结:

2. 组件通讯-props 基本使用

1.传递数据和接收数据的过程

2.函数组件使用 props 

3.类组件使用 props

总结:

3. 组件通讯-props 注意事项 

1.知道什么是单向数据流?

2.props 可以传递什么数据?任意 

总结:

4. 组件通讯-父传子方式 

1.父组件提供要传递的 state 数据

 2.给子组件标签添加属性,值为 state 中的数据

 3.子组件中通过 props 接收父组件中传递的数据

总结:

5. 组件通讯-子传父方式

1.父组件

 2.子组件

总结:

6.组件通讯-兄弟组件通讯

1.状态提升思想是什么?

2.参考代码

7. 组件通讯-context 跨级组件通讯

 1.什么是跨级组件通讯?

 2.context 怎么去理解?

3.演示使用 context 完成跨级组件通讯

总结:

1. 组件通讯-概念

了解组件通讯的意义 

大致步骤:

  • 知道组件的特点
  • 知道组件通讯意义

具体内容:

1.组件的特点

  • 组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据
  • 在组件化过程中,通常会将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能

2.知道组件通讯意义

  • 而在这个过程中,多个组件之间不可避免的要共享某些数据
  • 为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通
  • 这个过程就是组件通讯

总结:

  • 组件状态是独立的,组件化之后涉及状态同步,需要进行组件通讯

2. 组件通讯-props 基本使用

能够通过 props 传递数据和接收数据 

大致步骤:

  • 传递数据和接收数据的过程
  • 函数组件使用 props
  • 类组件使用 props

具体内容:

1.传递数据和接收数据的过程

  • 使用组件的时候通过属性绑定数据,在组件内部通过 props 获取即可。

2.函数组件使用 props 

  1.  
    // 使用组件
  2.  
    <Hello name="jack" age="20" />
  1.  
    // 定义组件 props包含{name:'jack',age:'20'}
  2.  
    function Hello(props) {
  3.  
    return <div>接收到数据:{props.name}</div>;
  4.  
    }

3.类组件使用 props

  1.  
    // 使用组件
  2.  
    <Hello name="jack" age="20" />
  1.  
    // 定义组件 props包含{name:'jack',age:'20'}
  2.  
    class Hello extends Component {
  3.  
    render() {
  4.  
    return <div>接收到的数据:{this.props.age}</div>;
  5.  
    }
  6.  
    }

总结:

  • props 是实现组件通讯的关键,它通过使用组件绑定属性,组件内部使用 props 来传值。

3. 组件通讯-props 注意事项 

知道 props 是单项数据流只读,但是可以传递任意数据。 

大致步骤:

  • 知道什么是单向数据流
  • 知道 props 可以传递什么数据

具体内容:

1.知道什么是单向数据流

  • 单向数据流,是从上到下的,自顶而下的,数据流。
  • 好比:河流,瀑布,只能从上往下流动,上游污染下游受影响,但是下游不能影响上游。
  • 父组件传递数据给子组件,父组件更新数据子组件自动接收更新后数据,当是子组件是不能修改数据的。

2.props 可以传递什么数据?任意 

  • 字符串
  • 数字
  • 布尔
  • 数组
  • 对象
  • 函数
  • JSX (插槽)

总结:

  • props 传递数据是单向的,可以传递任意格式的数据。

4. 组件通讯-父传子方式 

通过 props 将父组件的数据传递给子组件 

大致步骤:

  • 父组件提供要传递的 state 数据
  • 给子组件标签添加属性,值为 state 中的数据
  • 子组件中通过 props 接收父组件中传递的数据

具体代码:

1.父组件提供要传递的 state 数据

  1.  
    class Parent extends React.Component {
  2.  
    state = {
  3.  
    money: 10000,
  4.  
    };
  5.  
    render() {
  6.  
    return (
  7.  
    <div>
  8.  
    <h1>父组件:{this.state.money}</h1>
  9.  
    </div>
  10.  
    );
  11.  
    }
  12.  
    }

 2.给子组件标签添加属性,值为 state 中的数据

  1.  
    class Parent extends React.Component {
  2.  
    state = {
  3.  
    money: 10000
  4.  
    }
  5.  
    render() {
  6.  
    return (
  7.  
    <div>
  8.  
    <h1>父组件:{this.state.money}</h1>
  9.  
    + <Child money={this.state.money} />
  10.  
    </div>
  11.  
    )
  12.  
    }
  13.  
    }

 3.子组件中通过 props 接收父组件中传递的数据

  1.  
    function Child(props) {
  2.  
    return (
  3.  
    <div>
  4.  
    <h3>子组件:{props.money}</h3>
  5.  
    </div>
  6.  
    );
  7.  
    }

总结:

  • 父组件声明state,在子组件标签通过属性绑定,在子组件中通过props使用。

5. 组件通讯-子传父方式

通过 props 将子组件的数据传递给父组件

大致步骤:

  • 父组件提供回调函数,通过 props 传递给子组件
  • 子组件调用 props 中的回调函数,函数可传参
  • 父组件函数的参数就是子组件传递的数据

具体代码:

1.父组件

  1.  
    class Parent extends React.Component {
  2.  
    state = {
  3.  
    money: 10000,
  4.  
    };
  5.  
    // 回调函数
  6.  
    buyPhone = (price) => {
  7.  
    this.setState({
  8.  
    money: this.state.money - price,
  9.  
    });
  10.  
    };
  11.  
    render() {
  12.  
    const { money } = this.state;
  13.  
    return (
  14.  
    <div>
  15.  
    <h1>父组件:{money}</h1>
  16.  
    <Child money={money} buyPhone={this.buyPhone} />
  17.  
    </div>
  18.  
    );
  19.  
    }
  20.  
    }

 2.子组件

  1.  
    const Child = (props) => {
  2.  
    const handleClick = () => {
  3.  
    // 子组件调用父组件传递过来的回调函数
  4.  
    props.buyPhone(5000);
  5.  
    };
  6.  
    return (
  7.  
    <div>
  8.  
    <h3>子组件:{props.money}</h3>
  9.  
    <button onClick={handleClick}>买手机</button>
  10.  
    </div>
  11.  
    );
  12.  
    };

总结:

  • 子组件如何传递数据给父组件?触发父组件传递的回调函数传入数据
  • 父组件如何接收子组件的数据?回调函数的参数是子组件传递的数据
  • 父组件数据更新后,传递给子组件的数据是否更新?自动更新

6.组件通讯-兄弟组件通讯

 通过状态提升思想完成兄弟组件数据通讯

大致步骤:

  • 状态提升思想是什么?
  • 演示通过状态提升完成兄弟组件通讯。

具体内容:

1.状态提升思想是什么?

  • 将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态和修改状态的方法

 

  • 需要通讯的组件通过 props 接收状态和函数即可

2.参考代码

index.js

  1.  
    import React, { Component } from 'react';
  2.  
    import ReactDOM from 'react-dom';
  3.  
     
  4.  
    // 导入两个子组件
  5.  
    import Jack from './Jack';
  6.  
    import Rose from './Rose';
  7.  
     
  8.  
    // App 是父组件
  9.  
    class App extends Component {
  10.  
    // 1. 状态提升到父组件
  11.  
    state = {
  12.  
    msg: '',
  13.  
    };
  14.  
     
  15.  
    changeMsg = (msg) => {
  16.  
    this.setState({ msg });
  17.  
    };
  18.  
     
  19.  
    render() {
  20.  
    return (
  21.  
    <div>
  22.  
    <h1>我是App组件</h1>
  23.  
    {/* 兄弟组件 1 */}
  24.  
    <Jack changeMsg={this.changeMsg}></Jack>
  25.  
    {/* 兄弟组件 2 */}
  26.  
    <Rose msg={this.state.msg}></Rose>
  27.  
    </div>
  28.  
    );
  29.  
    }
  30.  
    }
  31.  
     
  32.  
    // 渲染组件
  33.  
    ReactDOM.render(<App />, document.getElementById('root'));

 Jack.js

  1.  
    import React, { Component } from 'react';
  2.  
     
  3.  
    export default class Jack extends Component {
  4.  
    say = () => {
  5.  
    // 修改数据
  6.  
    this.props.changeMsg('you jump i look');
  7.  
    };
  8.  
    render() {
  9.  
    return (
  10.  
    <div>
  11.  
    <h3>我是Jack组件</h3>
  12.  
    <button onClick={this.say}></button>
  13.  
    </div>
  14.  
    );
  15.  
    }
  16.  
    }

 Rose.jsx

  1.  
    import React, { Component } from 'react';
  2.  
     
  3.  
    export default class Rose extends Component {
  4.  
    render() {
  5.  
    return (
  6.  
    <div>
  7.  
    <h3>我是Rose组件-{this.props.msg}</h3>
  8.  
    </div>
  9.  
    );
  10.  
    }
  11.  
    }

7. 组件通讯-context 跨级组件通讯

掌握使用 context 实现跨级组件通讯 

大致步骤:

  • 什么是跨级组件通讯?
  • context 怎么去理解?
  • 演示使用 context 完成跨级组件通讯。

具体内容:

 1.什么是跨级组件通讯?

  • 组件间相隔多层,理解成叔侄,甚至更远的亲戚。

 2.context 怎么去理解?

  • 术语:上下文
  • 理解:一个范围,只要在这个范围内,就可以跨级组件通讯。(不需要 props 层层传递)

3.演示使用 context 完成跨级组件通讯

 index.jsx

  1.  
    import React, { Component, createContext } from 'react'
  2.  
    import Parent from './Parent'
  3.  
     
  4.  
    // 1. 创建上下文对象
  5.  
    // @ts-ignore
  6.  
    export const MyContext = createContext()
  7.  
     
  8.  
    export default class App extends Component {
  9.  
    state = {
  10.  
    money: 10000
  11.  
    }
  12.  
    updateMoney = newMoney => {
  13.  
    this.setState({
  14.  
    money: newMoney
  15.  
    })
  16.  
    }
  17.  
    render() {
  18.  
    return (
  19.  
    // 2. Provider包裹确定上下文生效范围,value注入范围内可用的数据
  20.  
    <MyContext.Provider value={{
  21.  
    money: this.state.money,
  22.  
    updateMoney: this.updateMoney
  23.  
    }}>
  24.  
    <div className="app">
  25.  
    <h1>根组件:{this.state.money}</h1>
  26.  
    <hr />
  27.  
    <Parent />
  28.  
    </div>
  29.  
    </MyContext.Provider>
  30.  
    )
  31.  
    }
  32.  
    }

 Parent.jsx

  1.  
    import Child from './Child';
  2.  
    const Parent = () => {
  3.  
    return (
  4.  
    <div className="parent">
  5.  
    <h3>父组件:</h3>
  6.  
    <hr />
  7.  
    <Child />
  8.  
    </div>
  9.  
    );
  10.  
    };
  11.  
     
  12.  
    export default Parent;

 Child.jsx

  1.  
    import { MyContext } from './App'
  2.  
     
  3.  
    const Child = () => {
  4.  
    return (
  5.  
    // 3. 通过Consumer来消费数据,value=>{ 这里使用数据 }
  6.  
    <MyContext.Consumer>
  7.  
    {(value) => (
  8.  
    <div className="child">
  9.  
    <h5>子组件:{value.money} <button onClick={()=>value.updateMoney(5000)}>修改money</button></h5>
  10.  
    </div>
  11.  
    )}
  12.  
    </MyContext.Consumer>
  13.  
    );
  14.  
    };
  15.  
     
  16.  
    export default Child;

总结:

  • 使用creatContext()创建一个上下文对象,包含:Provider Consumer 组件。
  • 使用 Provider 包裹组件,value 属性注入状态,函数,被包裹组件下的任何组件可以使用。
  • 使用 Consumer 消费 Provider 提供的数据和函数,语法{value=>使用数据和函数}