最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React搭配TypeScript使用教程及實(shí)戰(zhàn)案例

 更新時(shí)間:2026年02月13日 09:47:34   作者:一只秋刀魚  
本文主要介紹了React搭配TypeScript使用教程及實(shí)戰(zhàn)案例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、React與TypeScript搭配核心優(yōu)勢(shì)

TypeScript(簡(jiǎn)稱TS)是JavaScript的超集,核心優(yōu)勢(shì)是靜態(tài)類型檢查,能在開發(fā)階段發(fā)現(xiàn)類型錯(cuò)誤,避免運(yùn)行時(shí)bug;同時(shí)提供更清晰的代碼提示、更好的代碼可維護(hù)性和可擴(kuò)展性,尤其適合中大型React項(xiàng)目。

React與TS搭配的核心價(jià)值:

  • 組件Props類型約束:明確組件接收的參數(shù)類型、必填項(xiàng),減少傳參錯(cuò)誤;
  • 狀態(tài)(State)類型定義:規(guī)范狀態(tài)的數(shù)據(jù)結(jié)構(gòu),避免狀態(tài)賦值錯(cuò)誤;
  • 減少類型相關(guān)注釋:類型定義即文檔,提升團(tuán)隊(duì)協(xié)作效率;
  • IDE友好提示:自動(dòng)補(bǔ)全組件屬性、方法,降低開發(fā)成本。

二、環(huán)境搭建(React + TS)

2.1 快速創(chuàng)建React+TS項(xiàng)目

使用create-react-app快速初始化,自帶TS配置,無(wú)需手動(dòng)配置webpack、tsconfig.json:

# 方式1:npx(推薦,無(wú)需全局安裝)
npx create-react-app react-ts-demo --template typescript

# 方式2:yarn
yarn create react-app react-ts-demo --template typescript

項(xiàng)目創(chuàng)建完成后,核心文件說(shuō)明:

  • .tsx:React組件文件后綴(包含JSX語(yǔ)法,必須用.tsx);
  • .ts:非組件的TS文件(如工具函數(shù)、類型定義);
  • tsconfig.json:TS的核心配置文件(指定編譯選項(xiàng)、類型檢查規(guī)則);
  • react-app-env.d.ts:React與TS的類型聲明文件(自動(dòng)生成,無(wú)需修改)。

2.2 核心配置(tsconfig.json關(guān)鍵項(xiàng))

無(wú)需手動(dòng)修改默認(rèn)配置,重點(diǎn)了解以下關(guān)鍵項(xiàng),便于后續(xù)自定義:

{
  "compilerOptions": {
    "target": "ESNext", // 目標(biāo)JS版本
    "module": "ESNext", // 模塊規(guī)范
    "jsx": "react-jsx", // 支持JSX語(yǔ)法(React 17+ 推薦)
    "strict": true, // 開啟嚴(yán)格模式(推薦,強(qiáng)制類型檢查)
    "esModuleInterop": true, // 兼容CommonJS模塊
    "skipLibCheck": true, // 跳過(guò)第三方庫(kù)類型檢查
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true, // 支持導(dǎo)入JSON文件
    "isolatedModules": true,
    "noEmit": true // 不生成編譯后的JS文件(由create-react-app處理)
  },
  "include": ["src"] // 需要編譯的文件目錄
}

三、React+TS基礎(chǔ)使用(核心語(yǔ)法)

3.1 組件Props類型定義(最常用)

通過(guò)interface(接口)定義Props類型,明確組件接收的參數(shù),支持必填/可選、默認(rèn)值、聯(lián)合類型等。

import React from 'react';

// 1. 定義Props接口(首字母大寫,約定俗成)
interface UserCardProps {
  // 必填項(xiàng)(無(wú)?)
  name: string;
  age: number;
  // 可選項(xiàng)(加?)
  gender?: 'male' | 'female' | 'other'; // 聯(lián)合類型,限制可選值
  // 函數(shù)類型(定義回調(diào)函數(shù))
  onBtnClick: (id: number) => void;
}

// 2. 組件接收Props,指定類型為UserCardProps
const UserCard: React.FC<UserCardProps> = (props) => {
  // 解構(gòu)Props(更簡(jiǎn)潔)
  const { name, age, gender = 'other', onBtnClick } = props;
  return (
    <div className="user-card">
      <h3>{name}</h3>
      <p>年齡:{age}</p>
      <p>性別:{gender}</p>
      <button onClick={() => onBtnClick(123)}>點(diǎn)擊</button>
    </div>
  );
};

export default UserCard;

說(shuō)明:React.FC 是React函數(shù)組件的類型,泛型參數(shù)即為Props的類型;可選參數(shù)通過(guò)?標(biāo)記,可設(shè)置默認(rèn)值避免undefined。

3.2 組件State類型定義

使用useState時(shí),TS會(huì)自動(dòng)推斷狀態(tài)類型(類型推導(dǎo)),復(fù)雜狀態(tài)(如對(duì)象、數(shù)組)需手動(dòng)指定類型。

import React, { useState } from 'react';

// 1. 簡(jiǎn)單狀態(tài)(自動(dòng)推斷類型)
const SimpleState = () => {
  // TS自動(dòng)推斷count為number類型,setCount只能接收number
  const [count, setCount] = useState(0);
  // 錯(cuò)誤示例:setCount('123') → 類型不匹配,開發(fā)階段報(bào)錯(cuò)
  return <button onClick={() => setCount(count + 1)}>計(jì)數(shù):{count}</button>;
};

// 2. 復(fù)雜狀態(tài)(對(duì)象類型,手動(dòng)指定)
interface UserState {
  name: string;
  age: number;
  isLogin: boolean;
}

const ComplexState = () => {
  // 手動(dòng)指定狀態(tài)類型為UserState,初始值需符合該類型
  const [user, setUser] = useState<UserState>({
    name: '張三',
    age: 20,
    isLogin: false,
  });

  // 修改狀態(tài)(必須符合UserState類型)
  const login = () => {
    setUser({ ...user, isLogin: true });
  };

  return (
    <div>
      <p>{user.name}({user.age}歲)</p>
      <button onClick={login}>{user.isLogin ? '已登錄' : '登錄'}</button>
    </div>
  );
};

export default ComplexState;

3.3 事件處理類型定義

React事件有固定的TS類型(如點(diǎn)擊事件React.MouseEvent、輸入事件React.ChangeEvent),需指定事件類型和目標(biāo)元素類型。

import React, { useState } from 'react';

const EventDemo = () => {
  const [inputValue, setInputValue] = useState('');

  // 1. 點(diǎn)擊事件(React.MouseEvent,可指定目標(biāo)元素類型)
  const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
    console.log('按鈕點(diǎn)擊', e.target.innerText);
  };

  // 2. 輸入框變化事件(React.ChangeEvent,目標(biāo)為輸入框)
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    // e.target.value 自動(dòng)推斷為string類型
    setInputValue(e.target.value);
  };

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={handleInputChange}
        placeholder="請(qǐng)輸入內(nèi)容"
      />
      <button onClick={handleClick}>提交</button>
    </div>
  );
};

export default EventDemo;

3.4 自定義Hook類型定義

自定義Hook返回值為多個(gè)數(shù)據(jù)時(shí),需指定返回值類型(可通過(guò)元組、對(duì)象),確保使用時(shí)類型正確。

import React, { useState, useEffect } from 'react';

// 自定義Hook:獲取窗口寬度
// 定義返回值類型(元組類型,固定順序)
type UseWindowWidthReturn = [number, () => void];

const useWindowWidth = (): UseWindowWidthReturn => {
  const [width, setWidth] = useState(window.innerWidth);

  const updateWidth = () => {
    setWidth(window.innerWidth);
  };

  useEffect(() => {
    window.addEventListener('resize', updateWidth);
    return () => window.removeEventListener('resize', updateWidth);
  }, []);

  // 返回值必須符合UseWindowWidthReturn類型
  return [width, updateWidth];
};

// 使用自定義Hook
const WindowWidthDemo = () => {
  // 自動(dòng)推斷width為number,updateWidth為() => void
  const [width, updateWidth] = useWindowWidth();
  return <p>當(dāng)前窗口寬度:{width}px</p>;
};

export default WindowWidthDemo;

四、React+TS實(shí)戰(zhàn)案例(2個(gè)核心場(chǎng)景)

案例1:TodoList(基礎(chǔ)綜合案例)

涵蓋Props、State、事件處理、數(shù)組類型,適合新手入門,完整實(shí)現(xiàn)“添加、刪除、切換完成狀態(tài)”功能。

import React, { useState } from 'react';

// 1. 定義Todo類型(單個(gè)任務(wù))
interface Todo {
  id: number;
  text: string;
  done: boolean;
}

// 2. 定義TodoItem組件Props
interface TodoItemProps {
  todo: Todo;
  onToggle: (id: number) => void;
  onDelete: (id: number) => void;
}

// 3. 子組件:TodoItem
const TodoItem: React.FC<TodoItemProps> = ({ todo, onToggle, onDelete }) => {
  return (
    <li style={{ textDecoration: todo.done ? 'line-through' : 'none' }}>
      <input
        type="checkbox"
        checked={todo.done}
        onChange={() => onToggle(todo.id)}
      />
      <span>{todo.text}</span>
      <button onClick={() => onDelete(todo.id)} style={{ marginLeft: 10 }}>
        刪除
      </button>
    </li>
  );
};

// 4. 父組件:TodoList
const TodoList: React.FC = () => {
  // 狀態(tài):todo列表(數(shù)組類型,元素為Todo)
  const [todos, setTodos] = useState<Todo[]>([
    { id: 1, text: '學(xué)習(xí)React+TS', done: false },
    { id: 2, text: '完成實(shí)戰(zhàn)案例', done: true },
  ]);
  // 狀態(tài):輸入框內(nèi)容
  const [inputText, setInputText] = useState('');

  // 添加Todo
  const addTodo = (e: React.FormEvent) => {
    e.preventDefault(); // 阻止表單默認(rèn)提交
    if (!inputText.trim()) return;
    const newTodo: Todo = {
      id: Date.now(), // 用時(shí)間戳作為唯一id
      text: inputText,
      done: false,
    };
    setTodos([...todos, newTodo]);
    setInputText(''); // 清空輸入框
  };

  // 切換Todo完成狀態(tài)
  const toggleTodo = (id: number) => {
    setTodos(todos.map((todo) => (todo.id === id ? { ...todo, done: !todo.done } : todo)));
  };

  // 刪除Todo
  const deleteTodo = (id: number) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

  return (
    <div style={{ maxWidth: 500, margin: '0 auto', padding: 20 }}>
      <h2>TodoList(React+TS)</h2>
      <form onSubmit={addTodo} style={{ marginBottom: 20 }}>
        <input
          type="text"
          value={inputText}
          onChange={(e) => setInputText(e.target.value)}
          placeholder="請(qǐng)輸入任務(wù)"
          style={{ padding: 8, width: 300 }}
        />
        <button type="submit" style={{ padding: 8, marginLeft: 10 }}>
          添加
        </button>
      </form>
      <ul>
        {todos.map((todo) => (
          <TodoItem
            key={todo.id}
            todo={todo}
            onToggle={toggleTodo}
            onDelete={deleteTodo}
          />
        ))}
      </ul>
    </div>
  );
};

export default TodoList;

案例2:用戶列表(接口請(qǐng)求+復(fù)雜類型)

涵蓋接口請(qǐng)求(fetch/axios)、加載狀態(tài)、錯(cuò)誤處理、復(fù)雜對(duì)象類型,貼近真實(shí)項(xiàng)目場(chǎng)景,使用axios請(qǐng)求接口(需先安裝:npm install axios @types/axios)。

import React, { useState, useEffect } from 'react';
import axios from 'axios';

// 1. 定義用戶類型(接口返回?cái)?shù)據(jù)結(jié)構(gòu))
interface User {
  id: number;
  name: string;
  username: string;
  email: string;
  phone: string;
  website: string;
}

// 2. 定義接口返回類型(假設(shè)接口返回{ data: User[] })
interface UserResponse {
  data: User[];
}

const UserList: React.FC = () => {
  // 狀態(tài):用戶列表
  const [users, setUsers] = useState<User[]>([]);
  // 狀態(tài):加載狀態(tài)
  const [loading, setLoading] = useState<boolean>(true);
  // 狀態(tài):錯(cuò)誤信息
  const [error, setError] = useState<string | null>(null);

  // 接口請(qǐng)求( useEffect 模擬組件掛載時(shí)請(qǐng)求)
  useEffect(() => {
    const fetchUsers = async () => {
      try {
        setLoading(true);
        // 調(diào)用接口(示例接口:JSONPlaceholder)
        const response = await axios.get<UserResponse>('https://jsonplaceholder.typicode.com/users');
        // 接口返回?cái)?shù)據(jù)符合UserResponse類型,data為User數(shù)組
        setUsers(response.data.data);
        setError(null);
      } catch (err) {
        setError('請(qǐng)求用戶列表失敗,請(qǐng)稍后再試');
        console.error('請(qǐng)求錯(cuò)誤:', err);
      } finally {
        setLoading(false);
      }
    };

    fetchUsers();
  }, []);

  // 加載中
  if (loading) return <div style={{ textAlign: 'center', padding: 50 }}>加載中...</div>;
  // 錯(cuò)誤提示
  if (error) return <div style={{ textAlign: 'center', padding: 50, color: 'red' }}>{error}</div>;

  // 渲染用戶列表
  return (
    <div style={{ maxWidth: 800, margin: '0 auto', padding: 20 }}>
      <h2>用戶列表(React+TS+接口請(qǐng)求)</h2>
      <table border="1" style={{ width: '100%', borderCollapse: 'collapse', marginTop: 20 }}>
        <thead>
          <tr style={{ backgroundColor: '#f0f0f0' }}>
            <th style={{ padding: 10, textAlign: 'center' }}>ID</th>
            <th style={{ padding: 10, textAlign: 'center' }}>姓名</th>
            <th style={{ padding: 10, textAlign: 'center' }}>用戶名</th>
            <th style={{ padding: 10, textAlign: 'center' }}>郵箱</th>
            <th style={{ padding: 10, textAlign: 'center' }}>電話</th>
            <th style={{ padding: 10, textAlign: 'center' }}>網(wǎng)站</th>
          </tr>
        </thead>
        <tbody>
          {users.map((user) => (
            <tr key={user.id}>
              <td style={{ padding: 10, textAlign: 'center' }}>{user.id}</td>
              <td style={{ padding: 10, textAlign: 'center' }}>{user.name}</td>
              <td style={{ padding: 10, textAlign: 'center' }}>{user.username}</td>
              <td style={{ padding: 10, textAlign: 'center' }}>{user.email}</td>
              <td style={{ padding: 10, textAlign: 'center' }}>{user.phone}</td>
              <td style={{ padding: 10, textAlign: 'center' }}>
                <a href={`http://${user.website}`} target="_blank" rel="noopener noreferrer">
                  {user.website}
                </a>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default UserList;

五、常見問(wèn)題及解決方案

  • 問(wèn)題1:“Property 'xxx' does not exist on type 'never'”? 解決方案:復(fù)雜狀態(tài)(如數(shù)組、對(duì)象)初始值為空時(shí),TS無(wú)法推斷類型,需手動(dòng)指定泛型(如useState<User[]>([]))。
  • 問(wèn)題2:組件Props報(bào)錯(cuò)“Type 'undefined' is not assignable to type 'xxx'”? 解決方案:檢查Props是否為必填項(xiàng),若為可選項(xiàng)添加?,或給Props設(shè)置默認(rèn)值。
  • 問(wèn)題3:事件對(duì)象e報(bào)錯(cuò)“Property 'target' does not exist on type 'Event'”? 解決方案:指定事件類型(如React.MouseEvent<HTMLButtonElement>),明確目標(biāo)元素類型。
  • 問(wèn)題4:接口請(qǐng)求返回?cái)?shù)據(jù)類型不匹配? 解決方案:定義接口返回類型(如案例2中的UserResponse),axios請(qǐng)求時(shí)指定泛型(axios.get<UserResponse>(url))。

六、總結(jié)

React+TS的核心是“類型約束”,重點(diǎn)掌握3個(gè)核心點(diǎn):Props類型定義(interface)、State類型推導(dǎo)與手動(dòng)指定、事件類型定義。通過(guò)基礎(chǔ)語(yǔ)法練習(xí)和實(shí)戰(zhàn)案例,能快速適應(yīng)TS在React中的使用,尤其在中大型項(xiàng)目中,TS能顯著提升代碼質(zhì)量和開發(fā)效率。

到此這篇關(guān)于React搭配TypeScript使用教程及實(shí)戰(zhàn)案例的文章就介紹到這了,更多相關(guān)React搭配TypeScript使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React服務(wù)端渲染和同構(gòu)的實(shí)現(xiàn)

    React服務(wù)端渲染和同構(gòu)的實(shí)現(xiàn)

    本文主要介紹了React服務(wù)端渲染和同構(gòu)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫

    學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫

    這篇文章主要為大家介紹了學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • react+antd4實(shí)現(xiàn)優(yōu)化大批量接口請(qǐng)求

    react+antd4實(shí)現(xiàn)優(yōu)化大批量接口請(qǐng)求

    這篇文章主要為大家詳細(xì)介紹了如何使用react hooks + antd4實(shí)現(xiàn)大批量接口請(qǐng)求的前端優(yōu)化,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2024-02-02
  • React組件中監(jiān)聽函數(shù)獲取不到最新的state問(wèn)題

    React組件中監(jiān)聽函數(shù)獲取不到最新的state問(wèn)題

    這篇文章主要介紹了React組件中監(jiān)聽函數(shù)獲取不到最新的state問(wèn)題問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • react native 文字輪播的實(shí)現(xiàn)示例

    react native 文字輪播的實(shí)現(xiàn)示例

    這篇文章主要介紹了react native 文字輪播的實(shí)現(xiàn)示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • React中如何處理承諾demo

    React中如何處理承諾demo

    這篇文章主要為大家介紹了React中如何處理承諾demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React錯(cuò)誤的習(xí)慣用法分析詳解

    React錯(cuò)誤的習(xí)慣用法分析詳解

    這篇文章主要為大家介紹了React錯(cuò)誤用法習(xí)慣分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React渲染機(jī)制超詳細(xì)講解

    React渲染機(jī)制超詳細(xì)講解

    React整個(gè)的渲染機(jī)制就是React會(huì)調(diào)用render()函數(shù)構(gòu)建一棵Dom樹,在state/props發(fā)生改變的時(shí)候,render()函數(shù)會(huì)被再次調(diào)用渲染出另外一棵樹,重新渲染所有的節(jié)點(diǎn),構(gòu)造出新的虛擬Dom tree
    2022-11-11
  • React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)(左右聯(lián)動(dòng))

    React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)(左右聯(lián)動(dòng))

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 淺談React useTransition并發(fā)特性

    淺談React useTransition并發(fā)特性

    本文主要介紹了React的useTransition Hook,它可以幫助開發(fā)者將某些狀態(tài)更新標(biāo)記為“非緊急”,從而優(yōu)化用戶體驗(yàn),并提供了注意事項(xiàng)和性能優(yōu)化建議,感興趣的可以了解一下
    2026-05-05

最新評(píng)論

卓资县| 娱乐| 鲁山县| 绥江县| 贡嘎县| 白朗县| 普陀区| 璧山县| 枣强县| 黎川县| 杭锦后旗| 江孜县| 大庆市| 新晃| 巴青县| 台东县| 永顺县| 平安县| 平阳县| 泰安市| 张家界市| 广西| 财经| 凤冈县| 拉孜县| 中西区| 云霄县| 滦平县| 广南县| 宿迁市| 长白| 轮台县| 定西市| 乐至县| 隆化县| 得荣县| 陵川县| 商水县| 武定县| 密云县| 广德县|