react组件通信-父子;子父;兄弟;祖孙

目录

父传子

注意:

子传父

兄弟组件

跨组件通信Context


父传子

1.  父组件提供要传递的数据  -  `state` 
2.  给子组件标签`添加属性`值为 state中的数据 
3.  子组件中通过 `props` 接收父组件中传过来的数据 

4.  - 类组件可以使用this.props获取props对象
    - 函数式组件直接通过参数获取props对象

父组件: 初始化状态,子组件标签写 msg= {}

子组件:函数拿到msg: 参数props拿

               类拿到msg:this.props拿

扩展: {...info} 把info对象解构 一起传递给子组件 

import React from 'react'
import styles from './App.module.css'
import { FSon } from './FSon'
import { CSon } from './CSon'

export class Header extends React.Component {
  //初始化状态
  state = {
    message: '回来吃饭',
    info: {
      id: 1,
      name: 'hali',
    },
  }

  render() {
    const { message, info } = this.state
    return (
      <div className={styles.one}>
        <div>父</div>
        <FSon msg={message} {...info} />
        <CSon msg={message} {...info} />
      </div>
    )
  }
}

子组件 

import React from 'react'
import styles from './App.module.css'

// 函数式子组件
export const FSon = (props: any) => {
  const { msg, id, name } = props
  console.log('函数式子组件', props)
  return (
    <div className={styles.two}>
      <div>函数子组件:</div>
      {msg}
      <div>
        {id}
        {name}
      </div>
    </div>
  )
}
import React from 'react'
import styles from './App.module.css'

// 类子组件
export class CSon extends React.Component<any> {
  render() {
    console.log('类子组件', this)
    const { msg, id, name } = this.props
    return (
      <div className={styles.three}>
        <div>类子组件:</div>
        {msg}
        <div>
          {id}
          {name}
        </div>
      </div>
    )
  }
}

注意:

1.  props是只读对象(readonly)

根据单项数据流的要求,子组件只能读取props中的数据,不能进行修改

2. props可以传递任意数据

数字、字符串、布尔值、数组、对象、函数、JSX

子传父

父组件给子组件传递回调函数,子组件调用

父组件定义函数,通过props:changeMsg={this.changeMessage}传递函数给子组件

import React from 'react'
import styles from './App.module.css'
import { FSon } from './FSon'

export class Header extends React.Component {
  //初始化状态
  state = {
    message: '回来吃饭',
  }
  // 提供回调函数
  changeMessage = (newMsg: any) => {
    console.log('子组件传过来的数据:', newMsg)
    this.setState({
      message: newMsg,
    })
  }
  render() {
    const { message } = this.state
    return (
      <div className={styles.one}>
        <div>父</div>
        <FSon msg={message} changeMsg={this.changeMessage} />
      </div>
    )
  }
}

子组件通过props拿到父传过来的函数,点击触发父亲的函数并且传递数据给父亲,重新设置message的值

import React from 'react'
import styles from './App.module.css'

// 函数式子组件
export const FSon = (props: any) => {
  const { msg, changeMsg } = props
  const handleClick = () => {
    changeMsg('我就不回去')
  }
  return (
    <div className={styles.two}>
      <div>函数子组件:</div>
      {msg}
      <button onClick={handleClick}>change</button>
    </div>
  )
}

兄弟组件

可以先 子传给父 ,再把数据传递给 另外一个子,可以结合上面的俩种方法

跨组件通信Context

第一种写法

使用步骤:  

1.创建Context对象 导出 Provider 和 Consumer对象

2. 使用Provider包裹 最外层 组件提供数据

3.需要用到数据的 里层 组件使用Consumer包裹获取数据

import React, { createContext, ReactNode } from 'react'
import styles from './App.module.css'

// 1. 创建Context对象,并指定默认值的类型
const { Provider, Consumer } = createContext<string>('default value')

// 3. 消费数据
function ComC() {
  return (
    <div className={styles.three}>
      <Consumer>{(value) => <div>{value}</div>}</Consumer>
    </div>
  )
}

function ComA() {
  return (
    <div className={styles.two}>
      <ComC />
    </div>
  )
}

// 2. 提供数据
export class Header extends React.Component {
  state = {
    message: '孙子',
  }
  render() {
    console.log('父组件', this)
    const { message } = this.state
    return (
      <Provider value={message}>
        <div className={styles.one}>
          <ComA />
        </div>
      </Provider>
    )
  }
}

第二种写法 

使用步骤:

1.创建Context对象

import { createContext } from "react";

// 1. 创建Context对象,自己命名
export default createContext<any>({})

2.Context.Provider包裹后代组件 ,value提供数据

import React from 'react'
import styles from './App.module.css'
import { ComA } from './ComA'
import Context from './context'

// 2. Context.Provider包裹后代组件 ,value提供数据
// <Context.Provider value = {message}>
//    <ComA />
//</Context.Provider>
export class Header extends React.Component {
  state = {
    message: '孙子',
  }
  render() {
    console.log('父组件', this)
    const { message } = this.state
    return (
        <div className={styles.one}>
          <div>父组件:{message}</div>
          <Context.Provider value = {message}>
            <ComA />
          </Context.Provider>
        </div>
    )
  }
}

3.要使用数据就 const xxx = useContext(Context)拿到value值

import React, { useContext } from 'react'
import styles from './App.module.css'
import Context from './context'

// 3. 要使用数据就 const a = useContext(Context)拿到value值
export function ComC(props: any) {
  console.log('ComC',props);
  const messageOfC = useContext(Context)
  return (
    <div className={styles.three}>
    <div>孙子:{messageOfC}</div>
    </div>
  )
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值