在React中使用Typescript


在React中使用Typescript

最近學習的技術發現TS越來越多,於是自己嘗試做了幾個Demo實戰,發現TS上手不是很難,但是一旦出現錯誤很難百度到對應的文檔,而且在react中也不會使用ts來編寫

跟着這個文章走,內容可能會很長,一步一步去寫,保證你的React項目可以使用TS來編寫

本人寫的一個 TS+Hooks簡易版實戰

1. 創建一個React的TS項目

react的腳手架create-react-app默認支持TS的文件

npx create-react-app ts-demo --typescript

創建完會發現根目錄下面多了一個tsconfig.json文件

2. 使用Typescript編寫一個類組件

  • 類組件可以接受props,並且每個類組件都有state數據,所以他需要有兩個數據類型規范

子組件

import React from 'react'

interface IState {
	title:string
}

interface Iprops {
    count: number
}

class Child extends React.PureComponent<Iprops, IState> {
	state = {
    	title: 'ts'
	}
	render(){
        return <div>
            {this.state.title}
        	{this.props.count}
        </div>
    }
}

export default Child

父組件

import React from 'react'
import Child from './child'

interface IState {
	count: number
}

interface Iprops {}

class Parents extends React.PureComponent<Iprops, IState> {
	state = {
		count: 0
	}
	render(){
        return <Child count={count} />
    }
}

3.使用Typescript編寫一個函數組件

  • 由於函數組件的state使用的是鈎子一個一個勾進來的,所以他就需要一個泛型

子組件

import React from 'react'

interface Iprops {
	count: number
}

const Parent:React.FC<Iprops> = props => {
    const { count } = props;
    return <div>{count}</div>
}

父組件

import React, { useState } from 'react'
import Child from './child'

interface Iprops {}

const Child:React.FC<Iprops> = () => {
    const [count,setCount] = useState<number>(0)
    return <div>
        	<button onClick={()=>setCount(count+1)}>+1</button>
        	<Child count={count} />
        </div>
}

export default Child

4.在TS中使用react-router

個人查看對於react-router的影響較少

  • 當我們使用Route組件或者使用withRouter的時候,都會給組件綁定history,location,match三個屬性,但是props上面默認是沒有的,需要引入router對應的文件

初版

import React from 'react'
import { withRouter } from 'react-router-dom'

interface Iprops{}

const App:React.FC<Iprops> = props => {
    console.log(props.pathname) // 能打印出來結果,不過現在的props是any類型,並且沒有提示
    return <div></div>
}

export default withRouter(App)

使用TS

import React from 'react'
import { withRouter,RouteComponentProps } from 'react-router-dom'

interface Iprops extends RouteComponentProps{}

const App:React.FC<Iprops> = props => {
    console.log(props.pathname) // 有提示,並且props有他的類型規定
    return <div></div>
}

export default withRouter(App)

5.在TS中使用Redux

個人認為使用redux算是最麻煩的一步了

  • 這里面我選擇使用 react-redux,redux-thunk,redux

reducer

interface Iactions {
    type:string;
    value:any;
}
export interface Istate {
    count: number
}

const defaultState:Istate {
    count: 0
}

export default (state = defaultState, action: Iactions): Istate => {
    swtich(action.type){
        case 'add':
        	return {...state,count: state.count+1}
        default: 
        	return state;
    }
}

combineReducer

import { combineReducers } from "redux";
import User from "./reudcer";

export default combineReducers({
  User,
});

store

import { createStore, compose, applyMiddleware } from "redux";
import reducer from "./reudcers";
import thunk from "redux-thunk";
import { Istate } from "./reudcers/user"; //這個是為了在react-redux中的state設置

const composeEnhancers =
  typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
      })
    : compose;

const enhancer = composeEnhancers(applyMiddleware(thunk));

export interface StoreState {
  User: Istate;
}

const store = createStore(reducer, enhancer);

export default store;

注意: 這個地方會報錯,說windows上面沒有__REDUX_DEVTOOLS_EXTENSION_COMPOSE__這個屬性

在根目錄下面創建types目錄,再創建index.d.ts

// 修改ReduxTools工具
interface Window extends REDUXTOOS {
  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__:
    | string
    | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
}

declare var window: Window;

組件上

import React from 'react'
import { connect } from 'react-redux'
import { StoreState } from 'src/store'   //引入store中導出的state數據類型
import { setUserInfo } from 'src/store/action'

const App:React.FC<{}> = props => {
    const { count } = props;
    return <div>{count}</div>
}

export default connect(
  (state: StoreState) => ({
      count: state.User.count
  }),
  (dispatch: any) => {
    return {
      addCount(count: number) {
        dispatch(setUserInfo(count));
      },
    };
})(App)

6.引入第三方包

在引入第三方包文件的時候 比如react-redux的時候

import {connect} from 'react-redux' ,會發現報錯

當我們鼠標停留在react-redux上面的時候,會提示npm install @types/react-redux當我們安裝完成之后,我們的項目文件才算完整

總結

TS第一開始上手會感覺非常的困難,十步一報錯,而且代碼量也增加了

但是TS確是很多大型項目的都樂意去選擇的一個方向,感覺TS會越來越火,所以自己也在學習TS的過程中

分享一個自己正在寫的 TS+Hooks簡易版實戰


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM