在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簡易版實戰
