React-函数组件跟类组件的用法(React组件通信-父传子、React组件通信子传父、React兄弟组件通信) React组件通信 React中ref的使用

React函数组件用法

组件封装调用

import { useState } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
      {count}
      <br />
      {/* 调用子组件Son */}
      <Son />
    </>
  )
}

export default App
import { useCallback, useState } from "react"

const Son = ()=>{
    const [sonTitle] = useState('我是子组件')
    return<>
        {sonTitle}
    </>
}
export default Son

组件传值 父传子

使用属性的方式进行传参 子组件接受props

import { useState } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

function App() {
  const [count, setCount] = useState(0)
  const [fatherData,setFatherData] = useState('我是父组件的数据')
  return (
    <>
      {count}
      <br />
      {/* 调用子组件Son
      * @fatherData 给子组件传参
      */}
      <Son fatherData={fatherData}/>
    </>
  )
}

export default App

import { useCallback, useState } from "react"
/**
 * @fatherData
 * 使用解构的形式
 * 此处一定要设置默认值 不然报错概率大
 */
const Son = ({fatherData = ''})=>{
    const [sonTitle] = useState('我是子组件')
    return<>
        {sonTitle}
        {fatherData}
    </>
}
export default Son

组件传值子传父

将父组件的方法以参数的形式传入到子组件 子组件调用传参即可

import { useCallback, useState } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

function App() {
  const [count, setCount] = useState(0)
  const [fatherData,setFatherData] = useState('我是父组件的数据')
  const fatherFn = useCallback((SonProps:string):void=>{
    console.log(SonProps)
  })
  return (
    <>
      {count}
      <br />
      {/* 调用子组件Son
      * @fatherData 给子组件传参
      * @fatherFn 给子组件传参
      */}
      <Son fatherData={fatherData} fatherFn={fatherFn}/>
    </>
  )
}

export default App

import { useCallback, useState } from "react"
/**
 * @fatherData 
 * @fatherFn 父组件传递过来的方法用于给父组件传递参数
 * 使用解构的形式
 * 此处一定要设置默认值 不然报错概率大
 */
const Son = ({fatherData = '',fatherFn = ():void=>{}})=>{
    const [sonTitle] = useState('我是子组件')
    return<>
        {sonTitle}
        {fatherData}
        <button onClick={fatherFn.bind(null,'我是子组件传递过来的参数(bind)')}>
            点我给父组件传值 bind
        </button>
      {/* 推荐使用 */}
        <button onClick={()=>fatherFn('我是子组件传递过来的参数(箭头函数)')}>
            点我给父组件传值 箭头函数
        </button>
    </>
}
export default Son

父组件调用子组件的方法–ref

import { useCallback, useEffect, useRef, useState } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

function App() {
  const [count, setCount] = useState(0)
  const [fatherData,setFatherData] = useState('我是父组件的数据')
  const fatherFn = useCallback((SonProps:string):void=>{
    console.log(SonProps)
  })
  /**
   * @useRef 创建一个ref 给子组件绑定
   * @current 子组件暴露出来的都在current下
  */
  const refSon = useRef()
  const useSonFn = useCallback(()=>{
    console.log('子组件',refSon.current)
    // 调用子组件的方法
    refSon.current.sonFn()
  })
  useEffect(()=>{
    // 查看子组件
    console.log(refSon)
  },[])
  return (
    <>
      {count}
      <button onClick={useSonFn}> 调用子组件Son的方法</button>
      <br />
      {/* 调用子组件Son
      * @fatherData 给子组件传参
      */}
      <Son ref={refSon} fatherData={fatherData} fatherFn={fatherFn}/>
    </>
  )
}

export default App

import { forwardRef, useCallback, useImperativeHandle, useState } from "react"
/**
 * @fatherData 
 * @fatherFn 父组件传递过来的方法用于给父组件传递参数
 * 使用解构的形式
 * 此处一定要设置默认值 不然报错概率大
 */
const Son = ({fatherData = '',fatherFn = ():void=>{}},ref)=>{
    const [sonTitle] = useState('我是子组件')
    const sonFn = useCallback(()=>{
        console.log('父组件调用了我')
    })
    /**
     * @useImperativeHandle
     * 作用和vue3的defineExpose一样, 存储需要暴露给父组件让其获取的数据和函数
     */
      useImperativeHandle(ref,()=>({
        sonFn,
        sonTitle
      }));
    return<>
        {sonTitle}
        {fatherData}
        <button onClick={fatherFn.bind(null,'我是子组件传递过来的参数(bind)')}>
            点我给父组件传值 bind
        </button>
        <button onClick={()=>fatherFn('我是子组件传递过来的参数(箭头函数)')}>
            点我给父组件传值 箭头函数
        </button>
    </>
}
/**
 * @forwardRef
 * forwardRef作用: 封装组件, 直接将ref参数加在props后面(也可以不使用, 自己props定义一下ref需要传参, 父组件一样传ref就行)
 */
export default forwardRef(Son)

总结: 父组件用useRef() 子组件需要forwardRef 封装组件并且需要useImperativeHandle(ref,()=>({ })抛出

类式组件用法

组件封装

/**
 * @father组件 父组件
 */
import React, { ReactNode } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

export default class App extends React.Component{
  render(): ReactNode {
    return<>
      {/* 父组件 */}
      {/* 子组件 */}
      <Son />
    </>
  }
}
/**
 * @Son组件 子组件
 */
import React, { ReactNode } from "react"
export default class Son extends React.Component{

  render():ReactNode{
    return<>
      我是子组件
    </>
  }
}

组件传值 父传子

/**
 * @father组件 父组件
 */
import React, { ReactNode } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

export default class App extends React.Component{
  state={
    fatherData:'我是父组件传递过来的参数'
  }
  render(): ReactNode {
    return<>
      {/* 父组件 */}
      {/* 子组件 */}
      <Son fatherData={this.state.fatherData}/>
    </>
  }
}
/**
 * @Son组件 子组件
 */
import React from "react"
import PropTypes from 'prop-types'
export default class Son extends React.Component{
    static defaultProps: {
        fatherData: string //限制fatherData必传,且为字符串
    }
    render(){
        const {fatherData} = this.props
        return<>
            我是子组件
            {fatherData}
        </>
    }
}
Son.defaultProps = {
    fatherData:''  //限制fatherData必传,且为字符串
}
Son.propTypes = {
    //限制fatherData必传,且为字符串(PropTypes首字母必须大写)
    fatherData: PropTypes.string.isRequired  
  }

组件传值 子传父

/**
 * @father组件 父组件
 */
import React, { ReactNode } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

export default class App extends React.Component{
  state={
    fatherData:'我是父组件传递过来的参数'
  }
  
  fatherFn = (data:string='')=>{
       console.log('我是子组件传递过来的参数:',data) 
  }
  render(): ReactNode {
      return<>
      {/* 父组件 */}
      {/* 子组件 */}
      <Son fatherData={this.state.fatherData} fatherFn={this.fatherFn}/>
      </>
  }
}
/**
 * @Son组件 子组件
 */
import React from "react"
import PropTypes from 'prop-types'
export default class Son extends React.Component{
    static defaultProps: {
        fatherData: string, //限制fatherData必传,且为字符串
        // eslint-disable-next-line @typescript-eslint/ban-types
        fatherFn: Function
    }
    render(){
        const {fatherData,fatherFn} = this.props
        return<>
            我是子组件
            {fatherData}
            <button onClick={()=>fatherFn('子组件132')}>点我给父组件传参</button>
        </>
    }
}
Son.defaultProps = {
    fatherData:'',  //限制fatherData必传,且为字符串
    fatherFn:()=>{}
}
Son.propTypes = {
    //限制fatherData必传,且为字符串(PropTypes首字母必须大写)
    fatherData: PropTypes.string.isRequired, 
    fatherFn:PropTypes.func.isRequired
  }

父组件调用子组件的方法 --ref

/**
 * @father组件 父组件
 */
import React, { createRef, ReactNode } from 'react'
/**引入子组件Son */
import Son from './components/son'
import './App.css'

export default class App extends React.Component{
  state={
    fatherData:'我是父组件传递过来的参数'
  }
  public fatherFn = (data:string='')=>{
    console.log('我是子组件传递过来的参数:',data) 
  }
  public refSon = createRef(null)
  componentDidMount(): void {
      console.log(this.refSon.current)
      this.refSon.current.SonFn()
  }
  render(): ReactNode {
      return<>
      {/* 父组件 */}
      {/* 子组件 */}
      <Son ref={this.refSon} fatherData={this.state.fatherData} fatherFn={this.fatherFn}/>
      </>
  }
}
/**
 * @Son组件 子组件
 */
import React from "react"
import PropTypes from 'prop-types'
export default class Son extends React.Component{
    static defaultProps: {
        fatherData: string, //限制fatherData必传,且为字符串
        // eslint-disable-next-line @typescript-eslint/ban-types
        fatherFn: Function
    }
    public SonFn = ()=>{
        console.log('我是子组件的方法')
    }
    render(){
        const {fatherData,fatherFn} = this.props
        return<>
            我是子组件
            {fatherData}
            <button onClick={()=>fatherFn('子组件132')}>点我给父组件传参</button>
        </>
    }
}
Son.defaultProps = {
    fatherData:'',  //限制fatherData必传,且为字符串
    fatherFn:()=>{}
}
Son.propTypes = {
    //限制fatherData必传,且为字符串(PropTypes首字母必须大写)
    fatherData: PropTypes.string.isRequired, 
    fatherFn:PropTypes.func.isRequired
  }

兄弟组件传值–Context

// 创建并暴露Context对象
export const { Provider, Consumer } = React.createContext()


return (
      <div className='grandpa'>
        <h3>我是祖组件</h3>
        <h4>我的用户名是:{username}</h4>
        <h4>我的年龄是:{age}</h4>
        <button onClick={this.changeMessage}>点我更改信息</button>
        <Provider value={{ username, age }}>
          <Parent />
        </Provider>
      </div>
    )
// 导入Grandpa组件中暴露出来的Context对象的Consumer
import { Consumer } from './Grandpa'

return (
      <Consumer>
        {
          (value) => {
            return (<div className='son' >
              <h3>我是子组件</h3>
              <h4>我接收到的用户名是:{value.username}</h4>
              <h4>我接收到的年龄是:{value.age}</h4>
            </div >)
          }
        }
      </Consumer >

    )
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值