【组件开发笔记】类型检查-函数组件

给Props类型命名的方式 :

组件名+Props (比如BaseFormProps)

 

声明组件的方式:

1.使用FC类型声明

FCFunctionComponent的简写, 这个类型定义了默认的 props(如 children)以及一些静态属性(如 defaultProps)

import React, { FC } from 'react';

export const Component: FC<Props> = props => {
  return <div>组件内容</div>;
};
1
2
3
4
5
6
const BaseSelect: React.FC<Props> = (props) => {
……
return (
    <div>组件内容</div>;
)
}

  

2.直接使用普通函数声明:

1
2
3
4
5
6
7
export interface ComponentProps {
  ......
}
 
export function Component(props: ComponentProps) {
  return <div>内容</div>;
}

  

 

导出组件方式:

1
export default Component;

  

1
2
3
export default function Component(props: {}) {
  return <div>xxx</div>;
}

  

常用的defaultProps配置方式 :

 

1
2
3
4
Component.defaultProps = {
  formType: 'search',
  title:'默认标题'
};

  

1
export interface ComponentProps { <br>  name?: string; // 声明为可选属性 <br>}<br><br>// 利用对象默认属性值语法 <br>export const Component: FC<ComponentProps> = ({ name = 'TJ' }) => <div>Hello {name}!</div>;

  

泛型函数组件:

 

【泛型就是指定一个表示类型的变量,用它来代替某个实际的类型用于编程,而后通过实际调用时传入或推导的类型来对其进行替换,以达到一段使用泛型程序可以实际适应不同类型的目的。】

copy一段实例用以理解:

 

 因此泛型常用于列表或容器型的组件。例如我要写一个列表组件,接受到的list里的单项的数据类型,我要直接拿去返回给父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React from 'react';
 
export interface ListProps<T> {
  visible: boolean;
  list: T[];
  renderItem: (item: T, index: number) => React.ReactNode;
}
 
export function List<T>(props: ListProps<T>) {
  return <div />;
}
 
// Test
function Test() {
  return (
    <List
      list={[1, 2, 3]}
      renderItem={i => {
        /*自动推断i为number类型*/
      }}
    />
  );
}
 
【本例来自掘金·荒山的文章】

  

如果要在组件中声明子组件:

 

比如我写一个弹窗组件,里面要分出header和footer,那么可以在声明组件props的时候一起声明子组件的props,命名采用【ParentChildProps】的方式,例如ComponentHeaderProps;定义组件时也可以直接这么写:

1
2
3
4
5
6
7
8
Component.Header = (props: ComponentHeaderProps) => {
    return <div>我是头部</div>
};
 
// 整体:
<Component>
    <Component.Header>xxxxxx</Component.Header>
</Component>;

  

Forwarding Refs:

React.forwardRef用于转发 ref, 适用于 HOC(高阶组件) 和函数组件。

函数组件配合 forwardRef 和 useImperativeHandle 可以让函数组件向外暴露方法

举个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import React, { useRef, useState, useEffect, useImperativeHandle } from 'react';
 
const TheCreateForm = (props: Props) => {
  // 父级数据
  const {
    cRef,
    ......
  } = props;
 
 
  // 表单ref
  const form = useRef<any>();
 
 
  // 暴露给父级的方法 前缀都带
  useImperativeHandle(cRef, () => ({
    // 设置表单项
    setFields: (obj: any) => {
      return form.current.setFieldsValue(obj);
    },
    // 重置所有表单项
    resetFilds: () => {
      return form.current.resetFields();
    },
    // 显示表单
    showForm: (id?: number) => {
      if (!id) {
        // 新增表单
        setEdting(false);
        showNewForm('新增');
      } else if (editFormSource) {
        // 从初始化中编辑表单数据
        setEdting(true);
        showNewForm('修改', id);
      } else {
        setEdting(true);
        handleEdit(id);
      }
    },
    // 隐藏表单
    hideForm: () => {
      handeCancel();
    },
  }));

  

外层父组件就可以在cRef: React.createRef() 以后:

1
cRef.current.resetFilds();

  

 -------------------------

Context

【提供跨组件间状态共享机制】

【通过组件树提供一个传递数据的方法,避免了在每个层级手动传递 props 属性】

。记一下例子不然记不住

引入useContext :

1
import React, { FC, useContext } from 'react';

  

声明【Name+ContextValue格式命名】:

1
2
3
4
5
6
7
8
9
10
11
// 声明主题的主色调和副色调属性
export interface Theme {
  primary: string;
  secondary: string;
}
 
// 声明Context的属性
export interface ThemeContextValue {
  theme: Theme;
  onChange: (theme: Theme) => void;
}

  

 React.createContext 用于创建一个上下文容器(组件)

|---------------------------------------------------------------------------------------

|    小小栗子:

1
2
//  defaultValue用于设置共享的默认数据
const {Provider, Consumer} = React.createContext(defaultValue);

| Provider(生产者): 用于生产共享数据的地方。value:放置共享的数据。
 |  Consumer(消费者):消费 Provider 产生数据,需要嵌套在 Provider 下面才能通过回调拿到共享数据源,单独使用只能消费defaultValue
 
1
2
3
4
5
6
7
<Provider value={/*共享的数据*/}>
    /*里面可以渲染对应的内容*/
</Provider>
 
<Consumer>
  {value => /*根据上下文  进行渲染相应内容*/}
</Consumer>
|------------------------------------------------------


继续记录大牛的代码:


1
2
3
4
5
6
7
8
9
10
11
// 创建Context【以Name+Context命名】并设置默认值
 
export const ThemeContext = React.createContext<ThemeContextValue>({
  theme: {
    primary: 'red',
    secondary: 'blue',
  },
  onThemeChange: noop,
});
 
ps 查了一下noop是无操作的意思

  

创建生产者:

1
2
3
4
5
6
7
8
9
// Name+Provider命名
 
export const ThemeProvider: FC<{ theme: Theme; onThemeChange: (theme: Theme) => void }> = props => {
  return (
    <ThemeContext.Provider value={{ theme: props.theme, onThemeChange: props.onThemeChange }}>
      {props.children}
    </ThemeContext.Provider>
  );
};

  

这样通过钩子 useContext(ThemeContext) 就可以拿到里面的共享属性了。

比如在子组件里:

1
const { theme } = useContext(ThemeContext);

就可以直接使用theme,实现共享。

 

暴露hooks:

1
2
3
export function useTheme() {
  return useContext(ThemeContext);
}

  

 

 

 

 

 

posted @   芝麻小仙女  阅读(187)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示