antdPro+ts 项目踩坑记录

1,325 阅读3分钟

1、代理配置

被自己人坑了,接口是前端自己写的,采用strapi管理,在我这部分接口没有加/stone,别人的都加了,一通折腾没有发现问题,最终还是启动strapi,看了日志发现我接口调用了。

// 别人的接口
{
  "method": "GET",
  "path": "/stone/line-of-businesses",
  "handler": "line-of-business.find",
  "config": {
    "policies": []
  }
}
// 我的接口
{
  "method": "GET",
  "path": "/native-messages/count",
  "handler": "native-message.count",
  "config": {
    "policies": []
  }
}
// 最终修改
dev: {
    '/stone': {
      target: 'http://localhost:2021/',
      changeOrigin: true,
      pathRewrite: { '^/stone': '' },
    },
  }

2、函数组件类组件

一开始说函数组件高端,大气,上档次,就用了函数组件写,结果,我那个组件是一个头部组件,从接口拿数据给后边的子组件进行数据分发的,用了函数组件的useEffect,折腾了半天好容易接口调通了,数据怎么拿?崩了,函数组件没有自己的状态,全靠props传值,没有地方接这个返回值进行分发,然后改成了类组件又。。。

3、model.ts

model.ts文件是对对应组件的index.tsx文件的一个集中的状态管理的地方,会定义状态,异步方法,同步方法,具体用法和理解网上有很多,这里就不说了,只讲讲我踩的坑

import type { Effect, Reducer } from 'umi';
import type { CaseItemData } from './data.d' // 定义基础类型的文件
import { getMessageListData } from './serivce' // 定义的接口文件

export interface MLDataType {
  namespace: string;
  state: CaseItemData;
  effects: {
    fetchMLData: Effect;
  };
  reducers: {
    show: Reducer<CaseItemData>
  }
}

const initState = {
  MLData: []
}

// 这个const命名没看出啥用
const MessageListData: MLDataType = {
  // namespace:model数据层的命名,与view视图层作为连接的枢纽,
  // 就是用这个命名来使用model里的定义各种方法,和状态
  namespace: 'MessageListViewData',
  
  state: initState,

  effects: {
    *fetchMLData({ payload }, { call, put }) {
      const response = yield call(getMessageListData, payload)
      yield put({
        type: 'show',
        payload: {
          MLData: response
        }
      })
    }
  },

  reducers: {
    show(state, { payload }) {
      return {
        ...state,
        ...payload
      }
    }
  }
}

export default MessageListData;

还有一个点,在index.tsx里不用再import 这个model文件了,框架集成上去了,但是使用时必须写这个东西,connect连接,这样你才能再组件的index.tsx中调用model的方法,使用model的状态 PS: 当时调整组件的时候一直没有调接口,把所有的生命周期试了一遍,坑死人

export default connect(
// 命名空间的名称,namespace
  ({MessageListViewData}: {MessageListViewData: any}) => ({
    MessageListViewData
  })
// 当前组件名
)(Detail)

4、dav接口的异常处理

出现过一个问题,后端接口异常,在dva effects中没有进行异常处理,结果阻塞下面的流程,正常的逻辑是,上一次报错了,这一次应该可以正常请求。添加try catch后问题得到解决。但是为什么不加try catch就会阻断程序呢? 经查就是如果后台服务器返回类似400的错误,会导致call Effect抛出异常,最终会导致generator 停止运行。

image.png

这样就回阻断后边代码的运行,所以需要加try catch进行异常处理,每个接口都写try catch太麻烦,所以需要一个统一的异常处理方法,在src下添加app.ts文件,写入如下代码

export const dva = {
  config: {
    onError(e: { preventDefault: () => void; message: any }) {
      e.preventDefault()
      console.error(e.message)
    }
  }
}

就可以捕获接口异常进行统一处理,如果哪个需要单独处理,就还是使用try catch单独处理。

5、箭头函数

今天在写组件间方法调用的时候遇到一个报错

image.png

经过一通排查发现是代码里父组件的方法定义出现了问题,这里我定义方法用了具名函数的方式定义, 因为子组件是函数式组件,所以在子组件调用这个方法的时候,this取不到导致的报错。

getFetchMLData(page?: number, size?: number, message?: string) {
    const { dispatch } = this.props
    dispatch({
      type: 'MessageListViewData/fetchMLData',
      payload: {
        lineOfBusinessId: '1',
        message,
        pageNo: page,
        pageSize: size
      }
    })
  }

这也算是一个坑吧,就记住在react中写函数方法,箭头函数一般不会出错。