TypeScript 与 React 结合,可以为组件的 Props、State 和事件处理函数等添加强类型约束,这有助于提高代码的可读性和可靠性。以下是一些常见的 TypeScript 与 React 组件结合的示例。
1. 函数式组件(Function Component)
函数式组件是 React 中最常用的组件形式。我们可以通过 TypeScript 为 Props 添加类型。
import React from 'react';
// 定义 Props 类型
interface ButtonProps {
label: string;
onClick: () => void;
}
// 函数组件使用 Props 类型
const Button: React.FC<ButtonProps> = ({ label, onClick }) => {
return <button onClick={onClick}>{label}</button>;
};
// 使用组件
const App = () => {
return <Button label="Click me" onClick={() => alert('Clicked!')} />;
};
export default App;
- 说明:我们使用
React.FC<ButtonProps>来定义函数式组件的类型,并确保组件接收label和onClick作为 Props。
2. 类组件(Class Component)
虽然函数式组件较为流行,但类组件仍然存在一些应用场景。我们可以通过 TypeScript 为类组件的 Props 和 State 添加类型。
import React, { Component } from 'react';
// 定义 Props 和 State 类型
interface CounterProps {
initialCount: number;
}
interface CounterState {
count: number;
}
// 定义类组件并为 Props 和 State 添加类型
class Counter extends Component<CounterProps, CounterState> {
constructor(props: CounterProps) {
super(props);
this.state = {
count: props.initialCount,
};
}
increment = () => {
this.setState((prevState) => ({ count: prevState.count + 1 }));
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
// 使用组件
const App = () => {
return <Counter initialCount={0} />;
};
export default App;
- 说明:我们为
Props和State明确指定了类型,这样在使用和更新state时 TypeScript 会提供类型检查。
3. 处理事件(Event Handling)
处理事件时,可以为事件处理函数和事件对象指定类型。
import React from 'react';
const InputField: React.FC = () => {
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value);
};
return <input type="text" onChange={handleChange} />;
};
export default InputField;
- 说明:
React.ChangeEvent<HTMLInputElement>是onChange事件处理函数的事件类型。
4. 使用 useState 和 useEffect
在使用 React Hooks 时,TypeScript 也能为 useState 和 useEffect 添加类型。
import React, { useState, useEffect } from 'react';
const Counter: React.FC = () => {
// useState 的类型推断
const [count, setCount] = useState<number>(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Counter;
- 说明:
useState<number>(0)明确了count的类型是number,这样在setCount时就能确保赋值为数字。
5. 默认 Props 和可选 Props
使用 TypeScript 可以为 Props 提供默认值和可选值。
import React from 'react';
// 定义 Props 类型,`subtitle` 为可选
interface HeaderProps {
title: string;
subtitle?: string;
}
const Header: React.FC<HeaderProps> = ({ title, subtitle = 'Default Subtitle' }) => {
return (
<div>
<h1>{title}</h1>
<h2>{subtitle}</h2>
</div>
);
};
// 使用组件
const App = () => {
return <Header title="Hello, World!" />;
};
export default App;
- 说明:
subtitle?表示该属性是可选的,并且我们提供了一个默认值Default Subtitle。
6. 泛型组件
有时你可能需要编写一个可以处理不同类型的组件,这时可以使用泛型。
import React from 'react';
// 泛型组件定义
interface ListProps<T> {
items: T[];
render: (item: T) => React.ReactNode;
}
function List<T>({ items, render }: ListProps<T>) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{render(item)}</li>
))}
</ul>
);
}
// 使用泛型组件
const App = () => {
return (
<List items={['Apple', 'Banana', 'Cherry']} render={(item) => <span>{item}</span>} />
);
};
export default App;
- 说明:这里我们定义了一个泛型组件
List,它可以处理不同类型的items,并且使用泛型T来定义items和render函数的类型。
7. 高阶组件(Higher Order Component)
高阶组件是接受组件作为参数并返回新组件的函数。在 TypeScript 中,我们可以使用泛型为高阶组件的输入和输出组件提供类型。
import React, { ComponentType } from 'react';
// 定义一个高阶组件,它为 WrappedComponent 添加额外的功能
function withExtraProps<P>(WrappedComponent: ComponentType<P>) {
return (props: P) => {
const extraProp = 'This is an extra prop';
return <WrappedComponent {...props} extraProp={extraProp} />;
};
}
// 定义一个普通组件,包含 extraProp
interface MyComponentProps {
extraProp: string;
}
const MyComponent: React.FC<MyComponentProps> = ({ extraProp }) => {
return <div>{extraProp}</div>;
};
// 使用高阶组件包装 MyComponent
const EnhancedComponent = withExtraProps(MyComponent);
export default EnhancedComponent;
- 说明:
withExtraProps是一个高阶组件,它接受一个组件并返回一个新的组件,新的组件在props上增加了extraProp。
8. Context 与 TypeScript
使用 React Context 时,TypeScript 也可以为 Context 及其 Provider 和 Consumer 添加类型。
import React, { createContext, useContext } from 'react';
// 创建 Context,指定默认值的类型
interface ThemeContextType {
color: string;
toggleColor: () => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
// 创建一个使用 Context 的组件
const ThemeButton: React.FC = () => {
const theme = useContext(ThemeContext);
if (!theme) throw new Error('ThemeButton must be used within a ThemeProvider');
return <button style={{ backgroundColor: theme.color }} onClick={theme.toggleColor}>Toggle Theme</button>;
};
// 创建一个 Context Provider
const ThemeProvider: React.FC = ({ children }) => {
const [color, setColor] = React.useState('lightblue');
const toggleColor = () => {
setColor(prev => (prev === 'lightblue' ? 'darkblue' : 'lightblue'));
};
return (
<ThemeContext.Provider value={{ color, toggleColor }}>
{children}
</ThemeContext.Provider>
);
};
export default ThemeProvider;
- 说明:通过
createContext为上下文声明类型,并通过useContext针对Context进行类型检查。
总结
- 函数式组件 和 类组件 都可以结合 TypeScript 使用,为
Props和State提供类型。 - 常用的 React Hooks(如
useState和useEffect)也可以结合 TypeScript 显式声明类型。 - 高阶组件、泛型组件和 Context 都可以利用 TypeScript 提供强类型支持。
评论
使用 GitHub 账号登录后即可评论