React useImperativeHandle 子组件向父组件传值

父组件向子组件传值通过props传递,是很轻松的事。但在子组件中定义的useState,useRef值,要想在父组件中得到,却需要额外的props参数设置。

举例如下:

父组件:

 

子组件:

 关键解释如下:

父组件:

bond是一个ReactRef对象,存储在useState中,通过Son组件的bond props传递给Son组件。在父组件中通过调用bond.current就能调用子组件中包裹在useImpreativeHandle函数中的子组件函数,对子组件进行操作,这里调用getSonName是获取Son组件中的sonName值

子组件:

既然父组件需要获取我的值,那么,我就需要将在我的作用域内定义的值开放出来,通过使用React自带的useImpreativeHandle hooks就能做到这一点。

源码:

import React, { useState } from "react";

import Son from "./Son"

export default function Farther () {

    const [bond] = useState(React.createRef<{getSonName: () => string}>())

    const [fartherName] = useState("john")

    const sonName = bond.current?.getSonName()

    console.log(sonName)

    return <Son fartherName={fartherName} bond={bond} />

}

import React, { useImperativeHandle, useState } from "react";

export default function Son ({fartherName,bond}:{fartherName: string,bond: React.RefObject<{

    getSonName: () => string

}>}) {

    const [sonName] = useState("johnlove")

    const getSonName = () => {

        return sonName

    }

    useImperativeHandle(bond, () => {

        return{

          getSonName

        }

    })

    return <>

    {fartherName}

    </>

}

 

前言如释重负,好用的技术就应该越来越简单React Hooks 是 React 16.8 从提案转为正式加入的新特性。这个新特性是个非常棒的设计。 可以说对于React 技术栈的发展具分割线一样的意义。讲师在课程中提到:之前使用 React 作为主要的前端技术,开发一款网页游戏。在整个游戏的各个模块中,Redux ,mobx,以及蚂蚁金服的 ant-design,dva, umi 这些框架或者第三方库都有涉及使用。但是自从了解了Facebook官方提案的 Hooks 特性后,才真正觉得获得了前所未有的解脱。如果你有React开发经验,学习了解 Hooks 后,一定有一种如释重负的轻松感。React 带来了方便也带来了迷茫相信关心 React Hooks 这项新特性的童鞋,很多已经有了一定的 React 开发经验。那么你一定有所体验,React 给我们带来方便的同时,也的确和长久以来的前端开发模式有极大的不同。React 并不需要用继承,而是推荐用嵌套。React 有独特的 jsx 语法。大多数情况 jsx 都使得我们的代码更加简洁了。然而有些时候也给我们带来了一些困扰。 比如数据的递,逻辑的复用。 react 是一种 mvvm 的设计模式,作为开发者一定要清楚,那些数据是业务数据,那些数据是UI数据。否则你的代码很有可能会陷入混乱局面。大型项目中模块化与功能解耦困难在公司项目中 App 稍大的时候,我们发现状态提升和只通过 props 进行数据递。很多时候都很难实现我们的需求。这时无论我们是否清楚的了解,但是状态管理也就是 redux mobx 等,轻易地进入到了公司的项目中。我们经过初期的尝试发现状态管理,确实比用纯粹的 React 带来了数据递上的方便,以及代码组织上的清晰。但前提是你看懂且理解了 redux 大神晦涩的官网文档。 本来 React 被设计用来组件化前端开发。但当我们初期使用状态管理,我们常常会过度的使用状态数据,业务逻辑和ui逻辑没有清楚的分离,最终你的应用代码结果可能是:除了少数几个组件是独立的解耦的,大多数组件都因为状态数据的共享而耦合在了一起,且他们也完全依赖状态管理框架。无法再轻松的转移复用。使用高阶组件,属性渲染,渲染回调等高级特性,确实可以帮我们解决模块或功能的解耦问题。但是这些方法,确实有点超出普通“猿类”的技能。且降低了代码的可读性,对于团队协作,这是很致命的问题。React Hooks 真正开启前端模块化的金钥匙对于以上问题,React Hooks 都有很好的解决方案,官方的设计动机就是解决这些曾经的繁琐,化繁为简。React Hooks 让我们在纯函数中就可以使用 React 的众多特性。而不必使用类。代码扁平,易读。解耦状态相关逻辑,UI逻辑和业务逻辑更好的分离。这些逻辑往往是纯函数,而以前很容易混合在类组件中。通过自定义 Hooks 我们可以把应用中“状态相关”逻辑解耦出来,独立编写到我们自己的hooks 中。从而更加易于复用和独立测试。
### React子组件父组件的最佳实践 在 React 应用开发中,子组件父组件递数据是一种常见的需求。以下是实现这一功能的最佳实践: #### 方法一:通过回调函数 这是最常用的方式之一,在父组件中定义一个回调函数,并将其作为 `prop` 递给子组件。当子组件触发某些事件时调用该回调函数并将所需的数据作为参数递。 代码示例如下: ```javascript // 父组件 class Parent extends React.Component { state = { message: '' }; handleMessageFromChild = (msg) => { this.setState({ message: msg }); } render() { return ( <div> <p>来自子组件的消息: {this.state.message}</p> <Child onMessage={this.handleMessageFromChild} /> </div> ); } } // 子组件 class Child extends React.Component { sendMessageToParent = () => { const msg = '你好,父组件!'; this.props.onMessage(msg); } render() { return ( <button onClick={this.sendMessageToParent}>发送消息</button> ); } } ``` 这种方法的优点在于逻辑清晰且易于维护[^1]。 --- #### 方法二:使用函数式组件与 Hooks 随着 React 的发展,越来越多的应用倾向于采用函数式组件配合 Hooks 来管理状态和副作用。在这种情况下,可以利用 `useState` 和 `useCallback` 实现类似的回调机制。 代码示例如下: ```javascript import React, { useState, useCallback } from 'react'; function Parent() { const [message, setMessage] = useState(''); const handleChildMessage = useCallback((msg) => { setMessage(msg); }, []); return ( <div> <p>来自子组件的消息: {message}</p> <Child onMessage={handleChildMessage} /> </div> ); } const Child = ({ onMessage }) => { const handleClick = () => { const msg = '你好,父组件!'; onMessage(msg); }; return <button onClick={handleClick}>发送消息</button>; }; ``` 这种方式不仅保持了代码简洁性,还充分利用了现代 React 特性来优化性能[^2]。 --- #### 方法三:通过 Context API 或 Redux 进行全局状态管理 如果应用规模较大或者涉及多个层级之间的通信,则可以直接借助 **Context API** 或者第三方库如 **Redux** 来统一管理和共享状态。这样可以减少不必要的 Props 钻透问题(Prop Drilling),使整个应用程序的状态更加集中化。 简单例子如下: ```javascript // 创建上下文 const MessageContext = React.createContext(); // 提供者组件 function ProviderComponent() { const [message, setMessage] = React.useState('初始消息'); return ( <MessageContext.Provider value={{ message, setMessage }}> <Parent /> </MessageContext.Provider> ); } // 父组件 function Parent() { return <Child />; } // 子组件 function Child() { const { setMessage } = React.useContext(MessageContext); const updateMessage = () => { setMessage('更新后的消息'); }; return <button onClick={updateMessage}>修改消息</button>; } ``` 此方案适合复杂场景下的跨级通讯需求[^3]。 --- ### 总结 对于简单的父子关系之间的小范围交互推荐使用 **回调函数**;而对于更复杂的项目架构则建议引入 **Hooks** 或基于 **Context/Redux** 的解决方案以提升可读性和扩展能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值