zoukankan      html  css  js  c++  java
  • 在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简易版实战

  • 相关阅读:
    C# 异步(上)
    依赖注入框架Ninject
    依赖注入实例
    职场闲言
    Excel 使用VBA或宏----简单笔记
    Excel单元格锁定及解锁
    current transaction is aborted, commands ignored until end of transaction block
    JAVA_HOME is not defined correctly
    Multiple encodings set for module chunk explatform "GBK" will be used by compiler
    springBoot 整合 RabbitMQ 的坑
  • 原文地址:https://www.cnblogs.com/sunhang32/p/12830594.html
Copyright © 2011-2022 走看看