分享好友 编程语言首页 频道列表

React + TypeScript + Taro前端开发小结

typescript文章/教程  2023-02-09 10:200

前言

项目到一段落,先来记录一下,本文以前端新手的角度记录React、TypeScript、Taro相关技术的开发体验以及遇到的问题和解决方法。

之前总说要学React(这篇博客:代码使我头疼之React初学习),这次项目需要做H5前端+小程序,我终于能用上React了~

使用React的开发框架之前就听过京东的Taro,所以就这个了,直接开码。

关于React

不错,感觉比Vue的模板写法***很多,我看Taro文档的例子都是class组件,但一开始「前端带师」就推荐我用function组件,现在我全都是用function组件,react就该这么写,真香~

因为之前写了一段时间的Flutter,所以react对我来说很亲切,至少可以无缝上手声明式UI的写法。

不过我感觉React的生态太大,更新太快了,有点碎片化,很多第三方库官方文档都跟不上更新速度(批评一下mobx,害人不浅)

话说一开始我看了某位知乎大V的那本React和Redux的书,应该是我太菜的原因,感觉不是很容易理解,果然技术厉害的大佬不一定教书也厉害吗~

参考资料

关于TypeScript

第一次用TypeScript,不过作为日常用C#写后端的人,又处处是熟悉的感觉~

反正比JS好用一万倍就是了,类型提示真是太棒了

目前用得不深,后续有什么相关的我再写写博客记录一下。

参考资料

Taro框架使用感受

框架是个好框架,不过文档方面感觉还不是很完善,有些地方写得不是很清楚,感觉很多文档都是复制了微信小程序的文档来的,对于没开发过微信小程序且没读过微信官方文档的人来说,不是很友好。(不过官方文档还是要看,不看的话遇到很多问题都查不到的)

然后Taro官方提供了一个UI库,叫 TaroUI,用的话还是能用的,就是更新太慢了,它的github项目主页 显示上次更新时间还是去年(2021年)6月份,到现在近一年时间没动过了。最新稳定版本还在2.x,而Taro框架已经更新到3版本了。

因为我用的Taro框架是3.x版本,所以只能硬着头皮上TaroUI 3的beta版本,导致遇到了一些奇奇怪怪的问题,头大。

除了TaroUI这个界面库,Taro官方还提供另一个叫 NutUI 的库,不过是基于Vue的,我这个项目没法用,这个库就更新挺勤快的,github上最近更新还是6小时前,Star也有4.2k,比TaroUI的3.9k多。~~(看来React在京东不受待见呀~。

我还看到有一个叫 Taroify 的UI库,看起来好像不错,更新也很勤快,不过GitHub Stars只有300多,不敢用~ 下次来试试看

用的同时我还参考了这些项目/代码/文档:

接下来进入正题,总体说说遇到的一些问题/坑,以及解决方案。

页面路由问题

Taro封装了路由相关的方法,我是做完了项目有时间去翻一下 微信小程序文档 才发现这玩意跟小程序的路由特别像。

PS:我讨厌这种路由设计,不知道小程序这样是哪个人才想出来的,页面多了的话不太好维护啊~

app.config.ts 文件里把路由配置好,类似这样:

export default defineAppConfig({
  pages: [
    'pages/index/index',
    'pages/info/place',
    'pages/supply/index',
    'pages/user/login',
  ],
  window: {
    backgroundTextStyle: 'light',
    navigationBarBackgroundColor: '#fff',
    navigationBarTitleText: 'WeChat',
    navigationBarTextStyle: 'black'
  },
})

然后要跳转的地方就用 Taro.navigateTo({url: 'pages/user/login'}) 就行了

这里有个很坑的地方!Taro的热更新不完善,添加了新页面后热更新是不生效的,必须 yarn dev:h5 重启才能看到效果,一开始我被坑得嗷嗷叫~

地址参数问题

这个问题在我之前的博客:Django + Taro 前后端分离项目实现企业微信登录 有提到,Taro本身提供了 useRouter() 来给我们读取地址里的参数

比如上面那个路由跳转的地方我们加上了参数: Taro.navigateTo({url: 'pages/user/login?title=hello'})

那我们在 pages/user/login 页面里要获取参数就是这样

import {useEffect} from "react"
import {useRouter} from "@tarojs/taro"

export default function () {
    const router = useRouter()
    
    useEffect(() => {
        console.log(router.params.title)
    }, [])
}

但当在读取微信登录服务器回调参数的时候,就不行,就取不出来,得自己拿完整链接 window.location.href 去匹配。详见我这篇博客:Django + Taro 前后端分离项目实现企业微信登录

Taro.relaunch不会清除URL

这看起来不是什么大问题,不过也导致了一个小bug,就是我在使用微信登录后,注销登录的时候不会清除地址里的code,这样没关闭页面的情况下,再次使用微信登录,那个code还是旧的,就直接报错了~

TaroUI form的bug

说实话我不知道这是哪里的问题

只有一个页面出现了这个问题,在最后一个输入框按回车,表现是form提交,但其实也没提交,并且页面变成重新刷新了

百思不得其解

我只好在最后面再加了一个隐藏的input

<AtInput
    name='hide'
    onChange={() => {
    }}
    disabled={true}
    border={false}
    style={{display: 'none'}}/>

网络请求封装

Taro框架自带了 Taro.request 可以用来请求,不过我用的时候很奇怪一直提示跨域,因为前期时间很赶,我就没去深入,直接换成我之前vue项目封装好的axios,果然还是axios好用~

(不过之后做成小程序的话,应该还是得重构一下,据说小程序不支持formdata)

封装useState

感谢「前端带师 coppy」提供的代码~

import {useState} from 'react'

export default function useYourState<T extends {}>(state: T): [T, (state: Partial<T>) => void] {
  const [_state, _setState] = useState(state);
  return [
    _state,
    (state: Partial<T>) => {
      _setState((_state) => {
        return {
          ..._state,
          ...state
        };
      });
    }
  ];
}

这样就不需要每次setState都需要加...state

使用前:

import {useState} from 'react'

export const LoginPage = observer(() => {
  const [state, setState] = useState({
    username: '',
    password: '',
  })
  
  setState({
      ...state,
      username: '', password: ''
  })
}

使用后:

import useYourState from "@/utils/coppy_state";

export const LoginPage = observer(() => {
  const [state, setState] = useYourState({
    username: '',
    password: '',
  })
  
  setState({
      username: '', password: ''
  })
}

生产力获得了提高~

全局状态管理

没去用大名鼎鼎的redux,转而使用比较简单的mobx

但是找到的例子文档都不太行(举例,官方中文文档:https://cn.mobx.js.org/)

最终还是寻求「前端带师」的帮助,搞定了

坑点:

  • store现在没法用装饰器了,用这个makeAutoObservable
  • 不需要全局provider
  • Taro官网和例子可以说是史上最坑,千万别被骗了,地址:https://taro-docs.jd.com/taro/docs/mobx/
  • 请用最新版的mobx和mobx-react-lite,别用Taro官网那个4.8版本,太老了没用

代码

不需要全局provider包装了,直接用全局变量,当然也可以用React Context

store定义

import {makeAutoObservable} from "mobx";
import {User} from "@/models/user";
import * as auth from '@/utils/auth'

export class UserStore {
  isLogin = false
  user: User | null = null
  token = ''

  constructor() {
    makeAutoObservable(this)
  }

  login(user: User, token: string) {
    this.user = user
    this.token = token
    this.isLogin = true

    // 保存登录数据到本地
    auth.login(token, user.username)
  }

  logout() {
    this.isLogin = false
    this.user = null
    this.token = ''

    auth.logout()
  }
}

export const myUserStore = new UserStore()

组件使用

import {View} from "@tarojs/components"
import {AtButton} from "taro-ui";
import {observer} from "mobx-react-lite";
import {myUserStore} from "@/store/user";
import Taro from "@tarojs/taro";
import {useEffect} from "react";

export const UserPage = observer(() => {
  useEffect(() => {
    if (!myUserStore.isLogin) {
      Taro.redirectTo({url: '/pages/user/login'})
    }
  }, [])

  return (
    <View className='py-3 px-2'>
      <View className='at-article__h1'>用户中心</View>

      <View className='at-article__h3 mt-1'>用户名:{myUserStore.user?.first_name}</View>

      <AtButton className='mt-3' onClick={logout}>退出登录</AtButton>
    </View>
  )

  function logout() {
    myUserStore.logout()
    Taro.reLaunch({url: '/pages/index/index'})
  }
})

export default UserPage

参考资料

JSON反序列化class

使用这个库:https://github.com/typestack/class-transformer

model定义,这个定义可以用JSON来生成,有很多在线工具,比如:https://apihelper.jccore.cn/jsontool

export class User {
  username: string
  first_name: string
  last_name: string
  email: string
  date_joined: string
}

注意项目主页上的文档也是过期了的,plainToClass方法已过期,得用这个方法:plainToInstance

import {plainToInstance} from "class-transformer";

const user = plainToInstance(User, res.data.user)
myUserStore.login(user, res.data.token)

查看更多关于【typescript文章/教程】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
electron教程(番外篇二): 使用TypeScript版本的electron, VSCode调试TypeScript, TS版本的ESLint
electron教程(一): electron的安装和项目的创建electron教程(番外篇一): 开发环境及插件, VSCode调试, ESLint + Google JavaScript Style Guide代码规范electron教程(番外篇二): 使用TypeScript版本的electron, VSCode调试TypeScript, TS版本的ESLintelectron

0评论2023-03-08610

使用TypeScript,AngularJs和Web API构建基本的CRUD Web 应用
原文地址:using typescript with angularjs and web api 版权归其作者所有.在这篇文章中我将向大家展示如何使用TypeScript,Angular Js 和Asp.net Web API 来构建一个基本的实现CRUD功能的Web应用程序. Typescript提供了一系列的功能来方便程序员构造和组织更

0评论2023-02-10391

Typescript 中类的继承
Typescript中类的定义与继承与后端开发语言java/C#等非常像,实现起来非常方便,而且代码便于阅读。用Typescript写较大项目时是非常有优势的。/** * BaseClass */class BaseClass {constructor(name:string,age:number) {this.name=name;this.age=age;}name:s

0评论2023-02-09350

TypeScript实现设计模式——工厂模式
上回用typescript实现了单例模式,这回来实现工厂模式。工厂模式又分为简单工厂模式、工厂方法模式以及抽象工厂模式。简单工厂模式简单工厂模式通常在业务比较简单的情况下使用,它有三个部分组成:工厂类、抽象产品类、具体产品类。抽象产品类abstract class

0评论2023-02-09907

使用Visual Studio Code和typescript 开发调试React Native项目
关于React Native的详细介绍我就不叙述了,他是使用js构建原生app的开发框架。一次变编码多平台运行,非常强大。但是个人不喜欢js的过于灵活(弱类型)的语法。强大的强类型语言Typescript(简称TS)是我的首选,他可以编译成JavaScript,编译成的JavaScript代

0评论2023-02-09391

TypeScript的安装、使用及配置
JS是一种弱类型语言,对于代码的维护和重构是非常困难的。TypeScript是一个编译到纯JS的有类型定义的JS超集,可以极大的提升代码的健壮性。使用TS后,能够方便的查看函数定义、默认参数及类型、变量结构体等,同时对于IDE的参数类型提示也是非常友好的。优点

0评论2023-02-09713

vue-type-check: Vue 模板中的 Typescript 类型检查
越来越多人开始尝试使用 Typescript 编写他们的 vue 项目,vue 本身也在不断加强对 Typescript 的支持(官方提供 vue-class-component 库、使用 Typescript 编写 Vue 3.0 等),但是对于组件中模板部分的类型检查仍然有很大的局限性。为此我们开源了一个易

0评论2023-02-09756

JavaScript面向对象轻松入门之抽象(demo by ES5、ES6、TypeScript)
抽象的概念  狭义的抽象,也就是代码里的抽象,就是把一些相关联的业务逻辑分离成属性和方法(行为),这些属性和方法就可以构成一个对象。  这种抽象是为了把难以理解的代码归纳成与现实世界关联的概念,比如小狗这样一个对象:属性可以归纳出“毛色”、

0评论2023-02-09777

Angular2+typescript+webpack2(支持aot, tree shaking, lazy loading)
Angular2官方推荐的应该是使用systemjs加载, 但是当我使用到它的tree shaking的时候,发现如果使用systemjs+rollup,只能打包成一个文件,然后lazy loading就没法搞了。因此我使用了webpack2,webpack2自带tree shaking,只要将tsconfig中的module设置成es201

0评论2023-02-09811

Typescript学习笔记 TYPESCRIPT
TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。 安装 TypeScript命令行工具安装:npm install -g typescript编译一个 TypeScript 文件:tsc hello.ts  原始数据类型/ 任意值为每一个变量提前申明该类型,则该变量取值只能为申明的

0评论2023-02-09688

更多推荐