飘动的思绪 發表於 2020-5-5 14:16:00

在React中使用Typescript

<h1 id="在react中使用typescript">在React中使用Typescript</h1>
<p>最近学习的技术发现TS越来越多,于是自己尝试做了几个Demo实战,发现TS上手不是很难,但是一旦出现错误很难百度到对应的文档,而且在react中也不会使用ts来编写</p>
<p><font color="red"><strong>跟着这个文章走,内容可能会很长,一步一步去写,保证你的React项目可以使用TS来编写</strong></font></p>
<p>本人写的一个TS+Hooks简易版实战</p>
<h2 id="1-创建一个react的ts项目">1. 创建一个React的TS项目</h2>
<p>react的脚手架<code>create-react-app</code>默认支持TS的文件</p>
<pre><code class="language-js">npx create-react-app ts-demo --typescript
</code></pre>
<blockquote>
<p>创建完会发现根目录下面多了一个tsconfig.json文件</p>
</blockquote>
<h2 id="2-使用typescript编写一个类组件">2. 使用Typescript编写一个类组件</h2>
<ul>
<li>类组件可以接受props,并且每个类组件都有state数据,所以他需要有两个数据类型规范</li>
</ul>
<p><strong>子组件</strong></p>
<pre><code class="language-js">import React from 'react'

interface IState {
        title:string
}

interface Iprops {
    count: number
}

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

export default Child
</code></pre>
<p><strong>父组件</strong></p>
<pre><code>import React from 'react'
import Child from './child'

interface IState {
        count: number
}

interface Iprops {}

class Parents extends React.PureComponent&lt;Iprops, IState&gt; {
        state = {
                count: 0
        }
        render(){
      return &lt;Child count={count} /&gt;
    }
}
</code></pre>
<h2 id="3使用typescript编写一个函数组件">3.使用Typescript编写一个函数组件</h2>
<ul>
<li>由于函数组件的state使用的是钩子一个一个勾进来的,所以他就需要一个泛型</li>
</ul>
<p><strong>子组件</strong></p>
<pre><code class="language-js">import React from 'react'

interface Iprops {
        count: number
}

const Parent:React.FC&lt;Iprops&gt; = props =&gt; {
    const { count } = props;
    return &lt;div&gt;{count}&lt;/div&gt;
}
</code></pre>
<p><strong>父组件</strong></p>
<pre><code class="language-js">import React, { useState } from 'react'
import Child from './child'

interface Iprops {}

const Child:React.FC&lt;Iprops&gt; = () =&gt; {
    const = useState&lt;number&gt;(0)
    return &lt;div&gt;
              &lt;button onClick={()=&gt;setCount(count+1)}&gt;+1&lt;/button&gt;
              &lt;Child count={count} /&gt;
      &lt;/div&gt;
}

export default Child
</code></pre>
<h2 id="4在ts中使用react-router">4.在TS中使用react-router</h2>
<blockquote>
<p>个人查看对于react-router的影响较少</p>
</blockquote>
<ul>
<li>当我们使用<code>Route</code>组件或者使用<code>withRouter</code>的时候,都会给组件绑定<code>history,location,match</code>三个属性,但是props上面默认是没有的,需要引入router对应的文件</li>
</ul>
<p><strong>初版</strong></p>
<pre><code class="language-js">import React from 'react'
import { withRouter } from 'react-router-dom'

interface Iprops{}

const App:React.FC&lt;Iprops&gt; = props =&gt; {
    console.log(props.pathname) // 能打印出来结果,不过现在的props是any类型,并且没有提示
    return &lt;div&gt;&lt;/div&gt;
}

export default withRouter(App)
</code></pre>
<p><strong>使用TS</strong></p>
<pre><code class="language-js">import React from 'react'
import { withRouter,RouteComponentProps } from 'react-router-dom'

interface Iprops extends RouteComponentProps{}

const App:React.FC&lt;Iprops&gt; = props =&gt; {
    console.log(props.pathname) // 有提示,并且props有他的类型规定
    return &lt;div&gt;&lt;/div&gt;
}

export default withRouter(App)
</code></pre>
<h2 id="5在ts中使用redux">5.在TS中使用Redux</h2>
<blockquote>
<p>个人认为使用redux算是最麻烦的一步了</p>
</blockquote>
<ul>
<li>这里面我选择使用 <code>react-redux,redux-thunk,redux</code></li>
</ul>
<p><strong>reducer</strong></p>
<pre><code class="language-tsx">interface Iactions {
    type:string;
    value:any;
}
export interface Istate {
    count: number
}

const defaultState:Istate {
    count: 0
}

export default (state = defaultState, action: Iactions): Istate =&gt; {
    swtich(action.type){
      case 'add':
              return {...state,count: state.count+1}
      default:
              return state;
    }
}
</code></pre>
<p><strong>combineReducer</strong></p>
<pre><code class="language-js">import { combineReducers } from "redux";
import User from "./reudcer";

export default combineReducers({
User,
});

</code></pre>
<p><strong>store</strong></p>
<pre><code class="language-tsx">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" &amp;&amp; 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;
</code></pre>
<blockquote>
<p>注意: 这个地方会报错,说windows上面没有<code>__REDUX_DEVTOOLS_EXTENSION_COMPOSE__</code>这个属性</p>
</blockquote>
<p>在根目录下面创建<code>types</code>目录,再创建<code>index.d.ts</code></p>
<pre><code class="language-tsx">// 修改ReduxTools工具
interface Window extends REDUXTOOS {
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__:
    | string
    | __REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
}

declare var window: Window;
</code></pre>
<p><strong>组件上</strong></p>
<pre><code class="language-tsx">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&lt;{}&gt; = props =&gt; {
    const { count } = props;
    return &lt;div&gt;{count}&lt;/div&gt;
}

export default connect(
(state: StoreState) =&gt; ({
      count: state.User.count
}),
(dispatch: any) =&gt; {
    return {
      addCount(count: number) {
      dispatch(setUserInfo(count));
      },
    };
})(App)
</code></pre>
<h2 id="6引入第三方包">6.引入第三方包</h2>
<p>在引入第三方包文件的时候 比如<code>react-redux</code>的时候</p>
<p><code>import {connect} from 'react-redux' </code>,会发现报错</p>
<p>当我们鼠标停留在react-redux上面的时候,会提示<code>npm install @types/react-redux</code>当我们安装完成之后,我们的项目文件才算完整</p>
<h2 id="总结">总结</h2>
<p>TS第一开始上手会感觉非常的困难,十步一报错,而且代码量也增加了</p>
<p>但是TS确是很多大型项目的都乐意去选择的一个方向,感觉TS会越来越火,所以自己也在学习TS的过程中</p>
<p>分享一个自己正在写的TS+Hooks简易版实战</p>


</div>
<div id="MySignature" role="contentinfo">
    errors (99), warring (99)<br><br>
来源:https://www.cnblogs.com/sunhang32/p/12830594.html
頁: [1]
查看完整版本: 在React中使用Typescript