美文网首页React.jsWebpack
记 typescript React 项目中遇到的各种深坑。

记 typescript React 项目中遇到的各种深坑。

作者: 茶艺瑶 | 来源:发表于2018-10-20 16:02 被阅读125次

    首先本人用的是 React.js 因为再React + Typescript 使用中,提示会无比好用,要不你们使用Angular也可以,本人并不看好Vue的Ts版本.至少在现在的Vue2.5中,而未来的Vue3.0我也并不看好Vue的Ts

    typescript 文档在此 如果有C#、java基础 可只看变量定义即可

    在开发环境中建议使用Antd,文档清晰明了,Material UI官网文档等于没写。而且Antd本来就已经支持Ts,不需要另外下载@types/

    首先是 react react-dom 需要安装对应的 @types/react @types/react-dom 版本
    在定义Composer 组件的时候
    为了更好的管理项目
    需要定义两个接口interface

    interface Props { }
    interface State { }
    
    class Index extends React.PureComponent<Props, State> {
    
        constructor(props: Props) {
            super(props);
            this.state = {
            }
        }
    
        render() {
            return (
                <div className="container">
                     
                </div>
            )
        }
    }
    

    这样即可,如果你需要props 有参数定义就在Props 接口中定义你的行为和参数,如果不加?:那么你在父组件调用的时候,在编辑器中会提示你必须填写某些行为和参数.
    State 就是 定义 this.state 的行为和参数

    React-router 中的坑 (这了说的是 V4版本)

    @types/react-router 必须安装
    在V4中 你要使用 H5 的跳转的时候需要在 组件中使用 withRouter
    在Ts中,你需要在Props接口中继承 RouteComponentProps 这个接口

    interface Props extends RouteComponentProps { }
    
    export default withRouter(Index);
    

    以上组件之后,你便可使用this.props.hoisty.push() js 跳转 和 <Link /> 组件中实现跳转

    如果你使用的需要在路由中使用的Parmas参数的话,比就需要在定义一个接口RouterInfo,
    并且修改为一下

    interface RouterInfo {
      id:any
    }
    interface Props extends RouteComponentProps <RouterInfo >{ }
    

    这样的话你在编译的时候就不会出现出行this.props.match.params.id没有找到Id问题
    这里的params 适用于

    <React path='goodsList/:id.html' />
    

    这种模式中

    如果你是喜欢使用query的模式的话需要借助query-string

    如 URL 为 goodsList.html?id=1000

    const queryString = require('query-string');
    const parsed = queryString.parse(props.location.search);
    或者一下方法
    const search = props.location.search; // could be '?id=1000'
    const params = new URLSearchParams(search);
    const foo = params.get('id'); // bar
    

    Axios

    axios 无需下载 @types/axios的包 ,官方说在两年前就已经废除了这个包。
    使用方法和 axios 中和看云的中的文档一致,唯有那个拦截器是不一样的。

    import axios from 'axios';
    import { message } from 'antd';
    
    axios.defaults.baseURL = 'http://www.tpss.com/';
    
    message.config({
        top: 150
    })
    
    let hide: any;
    let here: boolean = false;
    
    const onRequestSuccess = (config: any) => {
        if (!here) {
            const n = message.loading('加载中', 0);
            hide = n;
            here = true;
        }
        return config;
    }
    
    const onResponseError = (response: any) => {
        if(here){
            setTimeout(hide, 500);
            here = false;
        }
        return response
    };
    
    axios.interceptors.request.use(onRequestSuccess);
    axios.interceptors.response.use(onResponseError);
    
    export default axios;
    

    这里是 Ts 可以通行的一种写法,你也可以直接使用axios 提供的 类,自己再封装一个

    import axios, {
      AxiosRequestConfig,
      AxiosResponse,
      AxiosError,
      AxiosInstance,
      AxiosAdapter,
      Cancel,
      CancelToken,
      CancelTokenSource,
      Canceler
    } from '../../';
    
    const config: AxiosRequestConfig = {
      url: '/user',
      method: 'get',
      baseURL: 'https://api.example.com/',
      transformRequest: (data: any) => '{"foo":"bar"}',
      transformResponse: [
        (data: any) => ({ baz: 'qux' })
      ],
      headers: { 'X-FOO': 'bar' },
      params: { id: 12345 },
      paramsSerializer: (params: any) => 'id=12345',
      data: { foo: 'bar' },
      timeout: 10000,
      withCredentials: true,
      auth: {
        username: 'janedoe',
        password: 's00pers3cret'
      },
      responseType: 'json',
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      onUploadProgress: (progressEvent: any) => {},
      onDownloadProgress: (progressEvent: any) => {},
      maxContentLength: 2000,
      validateStatus: (status: number) => status >= 200 && status < 300,
      maxRedirects: 5,
      proxy: {
        host: '127.0.0.1',
        port: 9000
      },
      cancelToken: new axios.CancelToken((cancel: Canceler) => {})
    };
    
    const handleResponse = (response: AxiosResponse) => {
      console.log(response.data);
      console.log(response.status);
      console.log(response.statusText);
      console.log(response.headers);
      console.log(response.config);
    };
    
    const handleError = (error: AxiosError) => {
      if (error.response) {
        console.log(error.response.data);
        console.log(error.response.status);
        console.log(error.response.headers);
      } else {
        console.log(error.message);
      }
    };
    
    axios(config)
      .then(handleResponse)
      .catch(handleError);
    
    axios.get('/user?id=12345')
      .then(handleResponse)
      .catch(handleError);
    
    axios.get('/user', { params: { id: 12345 } })
      .then(handleResponse)
      .catch(handleError);
    
    axios.head('/user')
      .then(handleResponse)
      .catch(handleError);
    
    axios.delete('/user')
      .then(handleResponse)
      .catch(handleError);
    
    axios.post('/user', { foo: 'bar' })
      .then(handleResponse)
      .catch(handleError);
    
    axios.post('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } })
      .then(handleResponse)
      .catch(handleError);
    
    axios.put('/user', { foo: 'bar' })
      .then(handleResponse)
      .catch(handleError);
    
    axios.patch('/user', { foo: 'bar' })
      .then(handleResponse)
      .catch(handleError);
    
    // Typed methods
    interface User {
      id: number;
      name: string;
    }
    
    // with default AxiosResponse<T> result
    
    const handleUserResponse = (response: AxiosResponse<User>) => {
        console.log(response.data.id);
        console.log(response.data.name);
        console.log(response.status);
        console.log(response.statusText);
        console.log(response.headers);
        console.log(response.config);
    };
    
    axios.get<User>('/user?id=12345')
        .then(handleUserResponse)
        .catch(handleError);
    
    axios.get<User>('/user', { params: { id: 12345 } })
        .then(handleUserResponse)
        .catch(handleError);
    
    axios.head<User>('/user')
        .then(handleUserResponse)
        .catch(handleError);
    
    axios.delete<User>('/user')
        .then(handleUserResponse)
        .catch(handleError);
    
    axios.post<User>('/user', { foo: 'bar' })
        .then(handleUserResponse)
        .catch(handleError);
    
    axios.post<User>('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } })
        .then(handleUserResponse)
        .catch(handleError);
    
    axios.put<User>('/user', { foo: 'bar' })
        .then(handleUserResponse)
        .catch(handleError);
    
    axios.patch<User>('/user', { foo: 'bar' })
        .then(handleUserResponse)
      .catch(handleError);
    
    // (Typed methods) with custom response type
    
    const handleStringResponse = (response: string) => {
      console.log(response)
    }
    
    axios.get<User, string>('/user?id=12345')
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.get<User, string>('/user', { params: { id: 12345 } })
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.head<User, string>('/user')
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.delete<User, string>('/user')
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.post<User, string>('/user', { foo: 'bar' })
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.post<User, string>('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } })
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.put<User, string>('/user', { foo: 'bar' })
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.patch<User, string>('/user', { foo: 'bar' })
      .then(handleStringResponse)
      .catch(handleError);
    
    axios.request<User, string>({
      method: 'get',
      url: '/user?id=12345'
    })
      .then(handleStringResponse)
      .catch(handleError);
    
    // Instances
    
    const instance1: AxiosInstance = axios.create();
    const instance2: AxiosInstance = axios.create(config);
    
    instance1(config)
      .then(handleResponse)
      .catch(handleError);
    
    instance1.request(config)
      .then(handleResponse)
      .catch(handleError);
    
    instance1.get('/user?id=12345')
      .then(handleResponse)
      .catch(handleError);
    
    instance1.get('/user', { params: { id: 12345 } })
      .then(handleResponse)
      .catch(handleError);
    
    instance1.post('/user', { foo: 'bar' })
      .then(handleResponse)
      .catch(handleError);
    
    instance1.post('/user', { foo: 'bar' }, { headers: { 'X-FOO': 'bar' } })
      .then(handleResponse)
      .catch(handleError);
    
    // Defaults
    
    axios.defaults.baseURL = 'https://api.example.com/';
    axios.defaults.headers.common['Authorization'] = 'token';
    axios.defaults.headers.post['X-FOO'] = 'bar';
    axios.defaults.timeout = 2500;
    
    instance1.defaults.baseURL = 'https://api.example.com/';
    instance1.defaults.headers.common['Authorization'] = 'token';
    instance1.defaults.headers.post['X-FOO'] = 'bar';
    instance1.defaults.timeout = 2500;
    
    // Interceptors
    
    const requestInterceptorId: number = axios.interceptors.request.use(
      (config: AxiosRequestConfig) => config,
      (error: any) => Promise.reject(error)
    );
    
    axios.interceptors.request.eject(requestInterceptorId);
    
    axios.interceptors.request.use(
      (config: AxiosRequestConfig) => Promise.resolve(config),
      (error: any) => Promise.reject(error)
    );
    
    axios.interceptors.request.use((config: AxiosRequestConfig) => config);
    axios.interceptors.request.use((config: AxiosRequestConfig) => Promise.resolve(config));
    
    const responseInterceptorId: number = axios.interceptors.response.use(
      (response: AxiosResponse) => response,
      (error: any) => Promise.reject(error)
    );
    
    axios.interceptors.response.eject(responseInterceptorId);
    
    axios.interceptors.response.use(
      (response: AxiosResponse) => Promise.resolve(response),
      (error: any) => Promise.reject(error)
    );
    
    axios.interceptors.response.use((response: AxiosResponse) => response);
    axios.interceptors.response.use((response: AxiosResponse) => Promise.resolve(response));
    
    // Adapters
    
    const adapter: AxiosAdapter = (config: AxiosRequestConfig) => {
      const response: AxiosResponse = {
        data: { foo: 'bar' },
        status: 200,
        statusText: 'OK',
        headers: { 'X-FOO': 'bar' },
        config
      };
      return Promise.resolve(response);
    };
    
    axios.defaults.adapter = adapter;
    
    // axios.all
    
    const promises = [
      Promise.resolve(1),
      Promise.resolve(2)
    ];
    
    const promise: Promise<number[]> = axios.all(promises);
    
    // axios.spread
    
    const fn1 = (a: number, b: number, c: number) => `${a}-${b}-${c}`;
    const fn2: (arr: number[]) => string = axios.spread(fn1);
    
    // Promises
    
    axios.get('/user')
      .then((response: AxiosResponse) => 'foo')
      .then((value: string) => {});
    
    axios.get('/user')
      .then((response: AxiosResponse) => Promise.resolve('foo'))
      .then((value: string) => {});
    
    axios.get('/user')
      .then((response: AxiosResponse) => 'foo', (error: any) => 'bar')
      .then((value: string) => {});
    
    axios.get('/user')
      .then((response: AxiosResponse) => 'foo', (error: any) => 123)
      .then((value: string | number) => {});
    
    axios.get('/user')
      .catch((error: any) => 'foo')
      .then((value: string) => {});
    
    axios.get('/user')
      .catch((error: any) => Promise.resolve('foo'))
      .then((value: string) => {});
    
    // Cancellation
    
    const source: CancelTokenSource = axios.CancelToken.source();
    
    axios.get('/user', {
      cancelToken: source.token
    }).catch((thrown: AxiosError | Cancel) => {
      if (axios.isCancel(thrown)) {
        const cancel: Cancel = thrown;
        console.log(cancel.message);
      }
    });
    
    source.cancel('Operation has been canceled.');
    

    less使用
    如果是用
    import * as styles from './index.less';

    需要一下配置

    webpack.config.js rules 中添加

     {
                    test: /\.less?$/,
                    use: ExtractTextPlugin.extract({
                        fallback: "style-loader",
                        use: [
                            {
                                loader: 'typings-for-css-modules-loader',
                                options: {
                                    modules: true,
                                    namedExport: true,
                                    camelCase: true,
                                }
                            },
                            'less-loader'
                        ]
                    })
                }
    

    相关文章

      网友评论

      • 十三以冬:谢谢分享,想请教您个问题。我也在用react+ts。编译时报错如下:这种报错一般什么原因啊?
        Error - [tsc] D:\reactTraining\redux-test\updateDashboard\node_modules\typescript\lib\tsc.js:55776
        throw e;
        ^

      本文标题:记 typescript React 项目中遇到的各种深坑。

      本文链接:https://www.haomeiwen.com/subject/zakmzftx.html