React.FC`<ChildComponentProps>`解释
代码场景
ParentComponent.tsx
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';function ParentComponent() {const [childData, setChildData] = useState<string>('');const handleChildData = (data: string) => { // 可以直接将set函数作为回调函数传递给子组件,而不需要额外封装一个函数setChildData(data);};return (<div><h1>Parent Component</h1><ChildComponent onData={handleChildData} /><p>Data from Child: {childData}</p></div>);
}export default ParentComponent;
ChildComponent.tsx
import React from 'react';interface ChildComponentProps {onData: (data: string) => void;
}const ChildComponent: React.FC<ChildComponentProps> = ({ onData }) => {const sendDataToParent = () => { // 可以直接调用onData函数,不用再封装一次onData('Data from Child');};return (<div><h2>Child Component</h2><button onClick={sendDataToParent}>Send Data to Parent</button></div>);
};export default ChildComponent;
在TypeScript中,React.FC<ChildComponentProps> 是用于定义 React 函数组件的一种类型注解。它有助于确保组件的属性(props)符合预期的类型,并为组件的使用提供类型安全和智能提示。
详细解释
React.FC是React.FunctionComponent的简写,是一个泛型接口,用于定义函数组件。ChildComponentProps是一个接口或类型别名,用于描述组件的 props 的结构和类型。
通过使用 React.FC<ChildComponentProps>,我们告诉 TypeScript 这个函数组件将接收的 props 必须符合 ChildComponentProps 接口的定义。
示例代码
定义 ChildComponentProps 接口
首先,我们定义一个接口 ChildComponentProps,描述这个组件所需要的 props 的类型:
interface ChildComponentProps {data: string; // props 中需要有一个字符串类型的 `data`
}
使用 React.FC<ChildComponentProps>
然后,我们定义一个函数组件 ChildComponent,并使用 React.FC<ChildComponentProps> 进行类型注解:
import React from 'react';interface ChildComponentProps {data: string;
}const ChildComponent: React.FC<ChildComponentProps> = ({ data }) => {return (<div><h2>Child Component</h2><p>{data}</p></div>);
};export default ChildComponent;
主要优势
-
类型安全:
- 确保组件接收的 props 符合预期的类型。在编写或使用组件时,如果提供的 props 类型不正确,TypeScript 会在编译时提示错误。
-
自动推断和提示:
- 使用
React.FC,TypeScript 会自动推断组件的返回类型为JSX.Element,并为 props 提供智能提示和自动补全。
- 使用
-
默认包含
children:React.FC默认包含了children属性,这对于需要传递子元素的组件非常方便。如果不需要children属性,可以显式地将其从接口中移除。
包含 children 属性
import React from 'react';interface ChildComponentProps {data: string;
}const ChildComponent: React.FC<ChildComponentProps> = ({ data, children }) => {return (<div><h2>Child Component</h2><p>{data}</p>{children}</div>);
};export default ChildComponent;
不包含 children 属性
如果你不希望组件接受 children 属性,可以将其显式移除:
import React, { ReactNode } from 'react';interface ChildComponentProps {data: string;children?: never; // 显式移除 `children` 属性
}const ChildComponent: React.FC<ChildComponentProps> = ({ data }) => {return (<div><h2>Child Component</h2><p>{data}</p></div>);
};export default ChildComponent;
总结
通过使用 React.FC<ChildComponentProps> 进行类型注解,你可以确保组件的 props 类型安全,并享受更好的开发体验,包括智能提示和自动补全。 这种类型注解在团队合作和大型项目中尤其重要,因为它可以显著减少由于类型错误引起的 bug。
React.FC使用场景
使用 React.FC(全称 React.FunctionComponent)是一种定义函数组件并为其添加类型注解的方式。是否使用 React.FC 是个人喜好和团队约定的结果。以下是一些常见的情况和一些额外的注意事项,帮助你决定何时使用 React.FC:
常见情况
- 组件有 props 传递进来:
- 当你的组件有 props 需要传递时,可以使用
React.FC<Props>来明确指定 props 的类型。
- 当你的组件有 props 需要传递时,可以使用
interface ChildComponentProps {data: string;
}const ChildComponent: React.FC<ChildComponentProps> = ({ data }) => {return (<div><h2>Child Component</h2><p>{data}</p></div>);
};
- 使用 children:
React.FC默认包括children属性,适用于那些需要接收子元素的组件。
interface ParentComponentProps {title: string;
}const ParentComponent: React.FC<ParentComponentProps> = ({ title, children }) => {return (<div><h1>{title}</h1>{children}</div>);
};
何时不用 React.FC
- 不需要
children属性:- 如果你的组件不需要
children属性,使用React.FC可能会增加不必要的属性,可以使用常规函数组件的方式。
- 如果你的组件不需要
interface ChildComponentProps {data: string;
}const ChildComponent = ({ data }: ChildComponentProps) => {return (<div><h2>Child Component</h2><p>{data}</p></div>);
};
- 避免默认 props 和 displayName 的影响:
- 使用
React.FC时,默认 props 和displayName会有一些不同的处理方式。如果你需要精确控制这些特性,可以选择不使用React.FC。
- 使用
interface ChildComponentProps {data: string;
}const ChildComponent = ({ data }: ChildComponentProps) => {return (<div><h2>Child Component</h2><p>{data}</p></div>);
};// 如果需要指定 displayName
ChildComponent.displayName = 'ChildComponent';
其他注意事项
- 定义返回类型:
React.FC会自动推断返回类型为JSX.Element,如果你不使用React.FC,可以手动指定返回类型。
interface ChildComponentProps {data: string;
}const ChildComponent: React.FC<ChildComponentProps> = ({ data }) => {return (<div><h2>Child Component</h2><p>{data}</p></div>);
};// 或者手动指定返回类型
const ChildComponent = ({ data }: ChildComponentProps): JSX.Element => {return (<div><h2>Child Component</h2><p>{data}</p></div>);
};
- 泛型组件:
- 对于泛型组件,使用
React.FC可能会增加复杂性,直接使用函数组件的方式可能更加简洁。
- 对于泛型组件,使用
interface ListComponentProps<T> {items: T[];
}function ListComponent<T>({ items }: ListComponentProps<T>): JSX.Element {return (<ul>{items.map((item, index) => (<li key={index}>{item}</li>))}</ul>);
}
总结
- 使用
React.FC是一种选择,不是强制的。它提供了一些默认行为(如children支持)和类型推断,但也增加了一些额外的类型。 - 在有 props 传递进来的情况下,使用
React.FC或手动定义 props 类型取决于个人和团队的喜好。 - 重要的是,在项目中保持一致的代码风格,并根据项目需求选择适合的方式。
通过这些解释和示例,希望能帮助你更好地理解何时使用 React.FC,何时选择其他方式定义 React 组件。
相关文章:
React.FC`<ChildComponentProps>`解释
代码场景 ParentComponent.tsx import React, { useState } from react; import ChildComponent from ./ChildComponent;function ParentComponent() {const [childData, setChildData] useState<string>();const handleChildData (data: string) > { // 可以直接…...
2024-06-24力扣每日一题
链接: 503. 下一个更大元素 II 题意 循环数组,找出每个元素的往后最近且大于它的元素 解: 今天没试暴力啊,大概率是过不了的 思路就是先找到最大的数,最大数的结果肯定是-1,然后倒着遍历数组…...
pyhon模块以及常用的第三方模块
import my_info as info print(info.name) info.show()from my_info import * print(name) show() pyhon中包的导入 import admin.my_admin as ad # 包名.模块名 admin是包名,my_admin是模块名print(ad.name) print(ad.info())from admin import my_admin as ad # …...
shell脚本—快速修改centos网络配置
shell-文本中自行修改想要的配置 #!/bin/bash# 网卡名称 eth"eth0"# IP 地址 ipaddr"192.168.1.100"# 子网掩码 netmask"255.255.255.0"# 网关 gateway"192.168.1.1"# 写入配置文件 echo "BOOTPROTOstatic" > /etc/sysc…...
线程池概念、线程池的不同创建方式、线程池的拒绝策略
文章目录 💐线程池概念以及什么是工厂模式💐标准库中的线程池💐什么是工厂模式?💐ThreadPoolExecutor💐模拟实现线程池 💐线程池概念以及什么是工厂模式 线程的诞生是因为,频繁的创…...
示例:WPF中如何绑定ContextMenu和Menu
一、目的:开发过程中,有些模块的右键ContextMenu菜单是需要动态显示的,既是根据不同条件显示不同的菜单,很多是通过代码去生成ContextMenu的MenuItem,本文介绍通过绑定的方式去加载ContextMenu,Menu菜单栏的…...
区块链小故事
大灰狼与小白兔 一天兔子妈妈出门了,在大门上安装了一个区块链的门把手,这个门把手只有兔子妈妈、小兔子、以及另一个客人都同意的时候,才会开门,有一天客人a的钥匙丢了,被大灰狼捡到了,大灰狼于是去开门&…...
Java | Leetcode Java题解之第167题两数之和II-输入有序数组
题目: 题解: class Solution {public int[] twoSum(int[] numbers, int target) {int low 0, high numbers.length - 1;while (low < high) {int sum numbers[low] numbers[high];if (sum target) {return new int[]{low 1, high 1};} else i…...
项目训练营第三天
项目训练营第三天 注册登录测试 前面我们编写了用户注册、登录的逻辑代码,每编写完一个功能模块之后,我们都要对该模块进行单元测试,来确保该功能模块的正确性。一般情况下使用快捷键Ctrl Shift Insert,鼠标左击类名可以自动生…...
计算机组成原理 | CPU子系统(1)基本概述
基本结构模型 运算与缓存部件 数据寄存部件 PSW不是很清楚 存储器是什么?属于那个结构里? 时序处理部件 cpu是大脑,控制器是神经元 ①通过硬件产生控制信号 ②通过软件产生控制信号 外频(系统时钟信号),…...
无引擎游戏开发(2):最简游戏框架 | EasyX制作井字棋小游戏I
一、EasyX中的坐标系 不同于数理中的坐标系,EasyX中的y轴是竖直向下的 二、渲染缓冲区 之前的程序添加了这三个函数改善了绘图时闪烁的情况: 小球在"画布“上移动的过程就是我们在调用绘图函数,这个”画布“就是渲染缓冲区,先绘制的内…...
排书 IDA*
原题链接 题目描述 给定 n 本书,编号为 1∼n。 在初始状态下,书是任意排列的。在每一次操作中,可以抽取其中连续的一段,再把这段插入到其他某个位置。我们的目标状态是把书按照 1∼n 的顺序依次排列。求最少需要多少次操作。 输…...
playwright录制脚本原理
Paywright录制工具UI 在上一篇博客中介绍了如何从0构建一款具备录制UI测试的小工具。此篇博客将从源码层面上梳理playwright录制原理。当打开playwright vscode插件时,点击录制按钮,会开启一个新浏览器,如下图所示,在新开浏览器页…...
awk脚本监控
awk脚本监控 使用脚本监控内存,cpu和硬盘的根目录,超过80%提示用户,写成函数库的行,每天早上 的8.50分,执行一次脚本 现在脚本中写需要的内容 cpuu () {aa$(top -b -n 1 |awk NR3 {printf "%.F",$2$4})if …...
Python高压电容导电体和水文椭圆微分
🎯要点 🎯二维热传导二阶偏微分方程 | 🎯调和函数和几何图曲率 | 🎯解潮汐波动方程 | 🎯解静止基态旋转球体流体运动函数 | 🎯水文空间插值 | 🎯流体流动模拟求解器 | 🎯随机算法解…...
微信小程序 引入MiniProgram Design失败
这tm MiniProgramDesign 是我用过最垃圾的框架没有之一 我按照官网的指示安装居然能安装不成功,牛! 这里说明我是用js开发的 到以上步骤没有报错什么都没有,然后在引入组件的时候报错 Component is not found in path “./miniprogram _npm/vant/weapp/button/index” (using…...
Java 8 Date and Time API
Java 8引入了新的日期和时间API,位于java.time包下,旨在替代旧的java.util.Date和java.util.Calendar类。新API更为简洁,易于使用,并且与Joda-Time库的一些理念相吻合。以下是Java 8 Date and Time API中几个核心类的简要概述&…...
pyppeteer模块经常使用的功能,相关操作案例
官方仓库地址:https://github.com/miyakogi/pyppeteer 官方文档地址:API Reference — Pyppeteer 0.0.25 documentation Selenium环境的相关配置比较繁琐,此外,有的网站会对selenium和webdriver进行识别和反爬,因此在…...
nginx+keepalived+tomcat集群实验
如遇星河 | nginx+keepalived高可用集群实验 木子87 | Keepalived+Nginx+Tomcat 实现高可用Web集群 环境 192.168.40.204 tomcat-1 192.168.40.138 tomcat-2 安装tomcat [root@bogon local]# vim /etc/profile 添加环境变量 JAVA_HOME=/usr/local/java PATH=$J…...
vue脚手架 axios的二次封装
目录 01 路由懒加载(重要) 02 axios在脚手架中的使用 03.axios的二次封装 04 组件缓存 01 路由懒加载(重要) 一次性导入会出现严重的问题 : 首屏卡顿 因为main.js中引入了router/index.js router/index.js又使用了import语句 静态的引入了每一个组件 导致了首屏卡顿 所以我…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
