IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> react hook组件间通讯的4种方式 -> 正文阅读

[JavaScript知识库]react hook组件间通讯的4种方式

前言

自从react官方引入了hook,很多小伙伴都从老的class组件换为hook组件,但因为hook组件的传参和class组件传参还是有些区别的,所以下文汇总了4种传参方式

一、父传子

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

1、父组件
import React, { useState } from 'react'

import ChildrenCom from './child'

// 父组件
const ParentCom = () => {
  const [name] = useState('A.Liang')

  return (
    <div>
      <h2>父组件</h2>
      <ChildrenCom name={name} />
    </div>
  )
}

export default ParentCom
2、子组件
import React, { useState } from 'react'

import ChildrenCom from './child'

// 父组件
import React, { useEffect } from 'react'

// 子组件
const ChildrenCom = props => {
  const { name } = props

  useEffect(() => {
    console.log('props==>', props)
  })

  return (
    <div>
      <h4>子组件: </h4>
      <p>父传给子组件的name: {name}</p>
    </div>
  )
}

export default ChildrenCom

二、子传父

父组件props传递回调函数给子组件

如果子组件想向父组件传递某些值,或者是子组件在执行某一段逻辑后想执行父组件中的某一段逻辑,此时可以在父组件中写好对应的逻辑函数,通过props传递这个函数给子组件进行调用即可

1、父组件
import React, { useState } from 'react'

import Child from './child'
// 父组件
const ParentCom = () => {
  const [count, setCount] = useState(0)

  // 获取子组件传过来的value值并设置到count,val参数就是子组件的value值
  const getChildrenValue = val => {
    setCount(val)
  }

  return (
    <div>
      <h2>父组件</h2>
      <p>获取子组件传过来的值:{count}</p>
      {/* 这里是重要代码,向子组件传递getValue这个prop,它的值是一个回调函数 */}
      <Child getValue={getChildrenValue} />
    </div>
  )
}

export default ParentCom
2、子组件
import React, { useState } from 'react'

// 子组件
const ChildrenCom = props => {
  const [value, setValue] = useState(0)

  const addValue = () => {
    setValue(value + 1)
    // 向父组件传递每次递增的value值
    props.getValue(value + 1)
  }

  return (
    <div>
      <h4>子组件</h4>
      <button onClick={addValue}>点击改变子组件的value值:{value}</button>
    </div>
  )
}

export default ChildrenCom

三、父传后代

使用useContext 实现跨组件传值

const value = useContext(MyContext);

useContext接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。

1、context.js
import { createContext } from 'react'

const myContext = createContext(null)

export default myContext
2、父组件
import React, { useReducer } from 'react'

import myContext from './createContext'
import Child from './child'

const reducer = (state, action) => {
  const [type, payload] = action
  switch (type) {
    case 'set':
      return {
        ...state,
        ...payload,
      }
    default:
      return {
        ...state,
        ...payload,
      }
  }
}

const initData = {
  name: 'A.Liang',
}

const ParentCom = () => {
  const [state, dispatch] = useReducer(reducer, initData)

  return (
    <div style={{ backgroundColor: '#f2f2f2' }}>
      <h1>Test最顶层组件----实现跨组件间传值。</h1>
      <button
        onClick={() => {
          dispatch(['set', { name: '父组件改变了名字' }])
        }}
      >
        点我修改name
      </button>
      <br />
      父组件-name:{state.name}
      <hr />
      <myContext.Provider
        value={{
          name: state.name,
          // 把最顶层Test组件的dispatch传递下去给后代组件,这样后代组件就都能修改最顶层组件的数据了。
          proDispatch: dispatch,
        }}
      >
        {/* 子组件 */}
        <Child />
      </myContext.Provider>
    </div>
  )
}

export default ParentCom
3、子组件
import React, { useContext } from 'react'

import myContext from './createContext'
import ChildChild from './child-child'

// 子组件
const ChildrenCom = () => {
  const { name, proDispatch } = useContext(myContext)

  function changeName() {
    proDispatch([
      'set',
      {
        name: '子组件修改了名字',
      },
    ])
  }

  return (
    <div>
      <h4>子组件: </h4>
      <button onClick={changeName}>子组件修改父组件的name</button>
      <p>父传给子组件的name: {name}</p>
      <ChildChild />
      <hr />
    </div>
  )
}

export default ChildrenCom
4、子孙组件
import React, { useContext } from 'react'

import myContext from './createContext'

// 子孙组件
const ChildrenCom = () => {
  const { name, proDispatch } = useContext(myContext)

  function changeName() {
    proDispatch([
      'set',
      {
        name: '子孙组件修改了名字',
      },
    ])
  }

  return (
    <div>
      <h4>子孙组件: </h4>
      <button onClick={changeName}>子孙组件修改父组件的name</button>
      <p>父传给子孙组件的name: {name}</p>
      <hr />
    </div>
  )
}

export default ChildrenCom

四、父调用子的函数

如果想在父组件中调用子组件的某个函数,或者是使用子组件的某个值,可以使用这个方式(尽量少用)

react官网的一段文字描述:
useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用

1、父组件
import React, { useRef } from 'react'

import ChildrenCom from './child'

// 父组件
const ParentCom = () => {
  // 获取子组件实例
  const childRef = useRef()

  // 调用子组件的onChange方法
  const onClickChange = () => {
    childRef.current.onChange()
  }

  return (
    <div>
      <h2>父组件</h2>
      <button onClick={onClickChange}>点击调用子组件onChange函数</button>
      <ChildrenCom ref={childRef} demonName="demo1" />
    </div>
  )
}

export default ParentCom
2、子组件
import React, {
  useState,
  useEffect,
  useImperativeHandle,
  forwardRef,
} from 'react'

// 子组件
const ChildrenCom = forwardRef((props, ref) => {
  const [value, setValue] = useState(0)
  const [name, setName] = useState('A.Liang')
  const { demonName } = props

  useEffect(() => {
    console.log('ref==>', ref)
  })

  // 自定义暴露给父组件的实例值 (useImperativeHandle 要配合 forwardRef使用)
  useImperativeHandle(ref, () => ({
    // 暴露函数给父组件调用
    onChange,
    // 也可以暴露子组件的状态值给父组件使用
  }))

  const onChange = () => {
    setValue(value + 1)
    setName(name === 'A.Liang' ? 'simon' : 'A.Liang')
  }

  return (
    <div>
      <h4>子组件: {demonName}</h4>
      <p>子组件的value: {value}</p>
      <p>子组件的name: {name}</p>
      <button onClick={onChange}>点击改变value和name</button>
    </div>
  )
})

export default ChildrenCom

代码下载(*p-hook**分支):https://gitee.com/staraliang/react17-app/tree/p-hook/

觉得本文写的不错的,希望点赞、收藏、加关注,每月不定期更新干货哦,谢谢您嘞!

你可能感兴趣的文章:

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 11:49:07  更:2022-01-28 11:50:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 13:33:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码