当前位置: 首页 > React学习笔记 > 正文
流量卡

React组件通讯

游魂 发表于2022年6月15日 11:20

组件通讯-概念

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

组件的特点

组件通讯意义

props 基本使用

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

函数组件使用 props

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

类组件使用 props

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

props 注意事项

什么是单向数据流

props 可以传递什么数据?

父传子方式

大致步骤:

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

class Parent extends React.Component {
  state = {
    money: 10000,
  };
  render() {
    return (
      <div>
        <h1>父组件:{this.state.money}</h1>
      </div>
    );
  }
}

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

class Parent extends React.Component {
  state = {
    money: 10000
  }
  render() {
    return (
      <div>
        <h1>父组件:{this.state.money}</h1>
+        <Child money={this.state.money} />
      </div>
    )
  }
}

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

function Child(props) {
  return (
    <div>
      <h3>子组件:{props.money}</h3>
    </div>
  );
}

子传父方式

父组件

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>
    );
  }
}

子组件

const Child = (props) => {
  const handleClick = () => {
    // 子组件调用父组件传递过来的回调函数
    props.buyPhone(5000);
  };
  return (
    <div>
      <h3>子组件:{props.money}</h3>
      <button onClick={handleClick}>买手机</button>
    </div>
  );
};

兄弟组件通讯

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

状态提升思想是什么?

1638944148017.c33b506e

参考代码:

index.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

// 导入两个子组件
import Jack from './Jack';
import Rose from './Rose';

// App 是父组件
class App extends Component {
  // 1. 状态提升到父组件
  state = {
    msg: '',
  };

  changeMsg = (msg) => {
    this.setState({ msg });
  };

  render() {
    return (
      <div>
        <h1>我是App组件</h1>
        {/* 兄弟组件 1 */}
        <Jack changeMsg={this.changeMsg}></Jack>
        {/* 兄弟组件 2 */}
        <Rose msg={this.state.msg}></Rose>
      </div>
    );
  }
}

// 渲染组件
ReactDOM.render(<App />, document.getElementById('root'));

Jack.js

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

import React, { Component } from 'react';

export default class Rose extends Component {
  render() {
    return (
      <div>
        <h3>我是Rose组件-{this.props.msg}</h3>
      </div>
    );
  }
}

context 跨级组件通讯

什么是跨级组件通讯?

context 怎么去理解?

1638932620946.11b91fb0

context 使用方法

context.js

import { createContext } from 'react' // 引入创建上下文的方法
export default createContext(初始值) // 初始值会在找不到Provider提供者时生效
import Context from './context'
import Child from './Child';

function Parent () {
  return (
    // Provider包裹确定上下文生效范围,value注入范围内可用的数据
      <Context.Provider value={context共享的值}>
        ....子孙组件
       </Context.Provider>
  )
}
import Context from './context'
function Child () {
  return (
      <Context.Consumer>
      {
        value => JSX
      }
    </Context.Consumer>
  )
}

index.jsx

import React, { Component, createContext } from 'react'
import Parent from './Parent'

// 1. 创建上下文对象
// @ts-ignore
export const MyContext = createContext()

export default class App extends Component {
  state = {
    money: 10000
  }
  updateMoney = newMoney => {
    this.setState({
      money: newMoney
    })
  }
  render() {
    return (
      // 2. Provider包裹确定上下文生效范围,value注入范围内可用的数据
      <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

import Child from './Child';
const Parent = () => {
  return (
    <div className="parent">
      <h3>父组件:</h3>
      <hr />
      <Child />
    </div>
  );
};

export default Parent;

Child.jsx

import { MyContext } from './App'

const Child = () => {
  return (
    // 3. 通过Consumer来消费数据,value=>{ 这里使用数据 }
    <MyContext.Consumer>
      {(value) => (
        <div className="child">
          <h5>子组件:{value.money} <button onClick={()=>value.updateMoney(5000)}>修改money</button></h5>
        </div>
      )}
    </MyContext.Consumer>
  );
};

export default Child;

总结:

全文完
本文标签: React组件React组件通讯React父子组件传值React兄弟组件传值组件传值父子组件传值propscontext跨级组件通讯
本文标题: React组件通讯
本文链接: https://www.iyouhun.com/m/?post=224

〓 随机文章推荐

共有2231阅 / 0我要评论
  1. 还没有评论呢,快抢沙发~

发表你的评论吧返回顶部

!评论内容需包含中文

请勾选本项再提交评论