开始学习React啦(二)

137 阅读3分钟

image-20210115235853572.png

一、组件间通信

组件间通信我们主要讲述下面几种情况:

  • 父组件给子组件传递

  • 子组件给父组件传递

  • 同级组件传递

  • 跨组件通信

父传子

只需要在父组件调用子组件的时候,将传递的信息加载子组件的属性中,子组件通过props接收父组件传递过来的值

父组件

function Father() {
  const data = { foo: "foo" }
  return (
    <Children data={data}></Children>
  )
}

子组件

function Children(props){
    const { data } = props // 接收父组件传递过来data的值
}

子传父

由于react中数据传递是单向的,数据流只能从父组件流向子组件

如果子要传递数据给父组件,可以首先在父组件中定义一个接收数据的回调函数,再将这个回调函数传递给子组件

父组件

class Father extends Component {
  state = {
    openKey : "friend" //应该展开项的 key 值,为空则都不展开
  } 
  openMenu = (name)=>{   // 1.定义一个接收子组件传递数据的函数
    this.setState({
      openKey: name
    });
  }
  render() {
    const {openKey} = this.state;
    return <div className="friend-list">
      <Children 
      	openMenu={openKey}  // 2.将函数传递给组件
      ></Children>
    </div>
  }
}

子组件

function Children(props){
    const { openMenu } = this.props
    return (
    	<button onClick={()=>{openMenu('子组件的值')}}  // 3.子组件将值传递给父组件
    )
}

同级组件传递

子组件间数据传递可以通过先将数据传给他们共同的父组件,再由父组件传给子组件

当一个子组件1想要给另一个子组件2传递数据,我们可以分解成以下几个步骤:

  • 父组件定义回调函数,将回调函数传递给子组件1,将值传递给子组件2
  • 子组件1接收父组件的回调函数,通过调用回调函数传递数据给父组件
  • 子组件2接收父组件传递过来的值,也就是子组件1传递给父组件2的值

代码演示下:

实例代码:

父组件定义回调函数,将回调函数传递给子组件1,将值传递给子组件2

class Father extends Component {
  state = {
    foo: "foo"
  }
  change = (value) => {
    this.setState({
      foo:value
    })
  }
  render() {
    return (
      <>
        <Children1 change={this.change}></Children1>  // 传递回调函数
        <Children2 data={this.state.foo}></Children2>  // 传递值
      </>
    )
  }
}

子组件1接收父组件的回调函数,通过调用回调函数传递数据给父组件

function Children1(props) {
  const { change } = props
  return (
    <button onClick={() => {
      change('子组件1的值')
    }}>子组件1</button>
  )
}

子组件2接收父组件传递过来的值,也就是子组件1传递给父组件2的值

function Children2(props) {
  const { data } = props  // 接收同级组件传递过来的值
  return (
    <p>{data}</p>
  )
}

跨组件

这里讲述React.createContext(defaultValue)

实现流程如下:

导入createContext

import {createContext} from "react";

创建上下文

const context = createContext();

context上下文中,存在ProviderConsumer组件

const {Provider,Consumer} = context;

Provider顾名思义,用来提供数据的

Consumer顾明思议,用来消费数据的,也就是得到数据

只需要在父组件中,通过Provider包裹组件,那么里面的组件都能得到该父组件传递过来的值

class App extends Component {
  state = {
    count: 1
  }
  add = () => {
    const { count } = this.state;
    this.setState({
      count:count + 1
    });
  }
  render() {
    const { count } = this.state;
    return <Provider
      value={{
        count:count,
        add:this.add
      }}
    >
        <Child />
    </Provider>
  }
}

Provider的组件,可以通过Consumer组件包裹得到数据

class SubChild extends Component {
  render() {
    console.log(this);
    return <>
        <Consumer>
          {(context)=>{  // Provide传递过来的value
              console.log(context);
              return <div></div>
          }}
        </Consumer>
    </>
  }
}

也可以通过contextType得到Provide数据

class SubChild extends Component {
  static contextType = context;
  render() {
    //console.log(this);
    const {count,add} = this.context;  // 得到Procider传递过来的值
    return <>
        <p>count:{count}</p>
        <button onClick={()=>{
          add();
        }}>递增</button>
    </>
  }
}

关于ConsumercontextType的区别:

  • Consumer书写起来不雅观,但是可以写多个Consumer得到各个Provider传递过来的值
  • contextType只能接收一个Provider传递过来的值