duhongjun / blog

my blog ~
https://duhongjun.github.io/blogsite
0 stars 0 forks source link

项目使用typescript的一些笔记 #5

Open duhongjun opened 6 years ago

duhongjun commented 6 years ago

0. 利用create-react-app初始化

create-react-app my-app --scripts-version=react-scripts-ts

react-native init MyApp --template typescript

1. 在tsx中引入图片报错

解决办法: 在项目根目录建立declaration.d.ts, 以jpeg为例:

declare module '*.jpeg' {
  const content: any
  export default content
}

2. 按需加载

以常用的lodash为例, 借助 ts-import-plugin, 代码如下:

      {
            test: /\.(ts|tsx)$/,
            include: paths.appSrc,
            loader: require.resolve('ts-loader'),
            options: {
              getCustomTransformers: () => ({
                before: [
                  tsImportPluginFactory([
                    {
                      style: false,
                      libraryName: 'lodash',
                      libraryDirectory: null,
                      camel2DashComponentName: false
                    }
                  ])
                ]
              })
            }
          }

lodash还需要在入口文件引入lodash/core

        // app.tsx
        import 'lodash/core'

就可以在项目中愉快的使用了~ (不过因为引入了core, 比使用babel按需加载要大10多kb)

     import { get, set } from 'lodash'

3. 扩展官方定义

项目使用axios, 项目中加入了自定义的属性用来在拦截器中进行一些操作.. 举个🌰

axios.interceptors.request.use(
  config => {
    if (config.name) {
      commonStore.setLoading(config.name, true)
    }
    if (!config.silentLoading) {
      commonStore.increaseLoadingCount()
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 调用时
axios.get('http://xxx.xxx', { params: { xxx }, silentLoading: true })

axios的AxiosRequestConfig接口中并没有我们自定义的属性, 就会报错, 解决办法就是扩展原有定义:

import axios from 'axios'
declare module 'axios' {
  interface AxiosRequestConfig {
    silentLoading?: boolean
    name?: string
  }
}

4. react封装过的事件对象的定义:

我们经常会用到对表单进行监听, 比如对Input的onChange, 正确的用法如下:

 // 例子是文本域, 如果是Input就使用 HTMLInputElement  其他类推
 // 关于 currentTarget 与 target的区别
 // https://stackoverflow.com/questions/5921413/difference-between-e-target-and-e-currenttarget
 handleOnchange = (e: React.FormEvent<HTMLTextAreaElement>) => {
    this.setState({
      newCommentsVal: e.currentTarget.value
    })
  }