跳到正文
当下的七炎
返回

TypeScript 与 React 结合常见的用法

编辑文章

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;

2. 类组件(Class Component)

虽然函数式组件较为流行,但类组件仍然存在一些应用场景。我们可以通过 TypeScript 为类组件的 PropsState 添加类型。

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;

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;

4. 使用 useStateuseEffect

在使用 React Hooks 时,TypeScript 也能为 useStateuseEffect 添加类型。

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;

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;

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;

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;

8. Context 与 TypeScript

使用 React Context 时,TypeScript 也可以为 Context 及其 ProviderConsumer 添加类型。

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;

总结


编辑文章
分享这篇文章:

评论

使用 GitHub 账号登录后即可评论


上一篇
前端Server-Sent Events通信
下一篇
TypeScript基本用法