Notes on React + TypeScript + Taro Frontend Development
Preface The project has reached a stopping point, so I'll jot some notes down first. This article records, from a frontend beginner's perspective, my development experience with React, TypeScript, and Taro, as well as the problems I ran into and how I solved them. I had always said I wanted to learn React (this blog post: Code Gives Me a Headache: First Steps with React). This project needed an H5 frontend plus a mini program, so I finally got to use React~ I had heard of JD's Taro as a React development framework before, so I went with that and started coding right away. About React Pretty good. It feels much freer than Vue's template syntax
目录17 个章节
Preface
The project has reached a stopping point, so I'll jot some notes down first. This article records, from a frontend beginner's perspective, my development experience with React, TypeScript, and Taro, as well as the problems I ran into and how I solved them.
I had always said I wanted to learn React (this blog post: Code Gives Me a Headache: First Steps with React). This project needed an H5 frontend plus a mini program, so I finally got to use React~
I had heard of JD's Taro as a React development framework before, so I went with that and started coding right away.
About React
Pretty good. It feels much freer than Vue's template syntax. The examples in the Taro docs are all class components, but from the start my "frontend mentor" recommended function components. Now I use function components for everything—this is how React should be written. So good~
Because I had written Flutter for a while before, React felt familiar to me. At least I could pick up the declarative UI style seamlessly.
But I feel React's ecosystem is too large and updates too fast—it's a bit fragmented. A lot of third-party libraries' official docs can't keep up with the update pace (a little criticism for MobX here—it really led people astray)
Speaking of which, at first I read some Zhihu influencer's book on React and Redux. Probably because I'm too much of a noob, it didn't feel very easy to understand. I guess being a technically strong expert doesn't necessarily mean you're also good at teaching~
References
- Getting Started with React - Understanding React from a JS Perspective: https://github.com/coppyC/blog/issues/16
About TypeScript
First time using TypeScript, but as someone who writes backends in C# day to day, it felt familiar all over again~
Anyway, it's ten thousand times better than JS, that's for sure. Type hints are just amazing.
I haven't used it very deeply yet. If I run into more related stuff later, I'll write another blog post about it.
References
- Exploring TypeScript Type Annotations - Custom Types: https://github.com/WowBar/blog/issues/9
Impressions of the Taro Framework
The framework is a good framework, but the documentation doesn't feel very complete yet. Some parts aren't written very clearly. A lot of the docs feel like they were copied from the WeChat Mini Program docs, which isn't very friendly for people who haven't developed WeChat Mini Programs and haven't read the official WeChat docs. (You still need to read the official docs though—otherwise you won't be able to look up a lot of the problems you run into.)
Taro officially provides a UI library called TaroUI. It's usable, just that updates are too slow. Its GitHub project page shows the last update was still June of last year (2021)—it hasn't been touched in nearly a year. The latest stable version is still 2.x, while the Taro framework has already been updated to version 3.
Since I was using Taro 3.x, I had no choice but to grit my teeth and use the TaroUI 3 beta, which led to some weird issues. What a headache.
Besides the TaroUI UI library, Taro also officially provides another library called NutUI, but it's Vue-based, so I couldn't use it for this project. That library is updated quite diligently—the latest update on GitHub was still 6 hours ago, and it also has 4.2k stars, more than TaroUI's 3.9k. (Looks like React isn't favored at JD~).
I also saw a UI library called Taroify. It looks pretty good and is updated frequently too, but it only has a little over 300 GitHub stars, so I didn't dare use it~ I'll try it next time.
While using it I also referred to these projects/code/docs:
- https://github.com/NervJS/taro-v2ex/blob/react/src/pages/thread_detail/thread_detail.tsx
- https://github.com/wuba/Taro-Mortgage-Calculator
- https://github.com/NervJS/awesome-taro
Now on to the main topic. Overall I'll talk about some issues/pitfalls I ran into, and the solutions.
Page Routing Issues
Taro wraps routing-related methods. It wasn't until I finished the project and had time to flip through the WeChat Mini Program docs that I realized this thing is especially similar to mini program routing.
PS: I hate this kind of routing design. I don't know which genius came up with this for mini programs. When there are a lot of pages it's not easy to maintain~
Configure the routes in the app.config.ts file, something like this:
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'
},
})
Then wherever you need to navigate, just use Taro.navigateTo({url: 'pages/user/login'})
Here's a real pitfall! Taro's hot reload is incomplete. After adding a new page, hot reload doesn't take effect—you have to restart with yarn dev:h5 to see the result. I got burned by this at the start and was howling~
URL Parameter Issues
I mentioned this issue in a previous blog post: Implementing Enterprise WeChat Login in a Django + Taro Decoupled Frontend-Backend Project. Taro itself provides useRouter() for us to read parameters from the URL.
For example, if we add parameters at that navigation above: Taro.navigateTo({url: 'pages/user/login?title=hello'})
Then getting the parameters in the pages/user/login page would be like this
import {useEffect} from "react"
import {useRouter} from "@tarojs/taro"
export default function () {
const router = useRouter()
useEffect(() => {
console.log(router.params.title)
}, [])
}
But when reading the WeChat login server callback parameters, it doesn't work—you just can't get them. You have to take the full URL window.location.href and match it yourself. See this blog post of mine for details: Implementing Enterprise WeChat Login in a Django + Taro Decoupled Frontend-Backend Project
Taro.relaunch Doesn't Clear the URL
This doesn't look like a big issue, but it did cause a small bug: after using WeChat login, logging out doesn't clear the code in the URL. So if you don't close the page and use WeChat login again, that code is still the old one, and it just errors out~
TaroUI Form Bug
To be honest I don't know where this problem comes from
Only one page had this issue. Pressing Enter in the last input box looked like a form submit, but it didn't actually submit, and the page refreshed instead.
I just couldn't figure it out no matter how hard I thought
I had no choice but to add a hidden input at the very end
<AtInput
name='hide'
onChange={() => {
}}
disabled={true}
border={false}
style={{display: 'none'}}/>
Wrapping Network Requests
The Taro framework comes with Taro.request that can be used for requests, but when I used it I kept getting weird CORS errors. Because time was tight early on, I didn't dig into it and just switched to the axios wrapper I had from a previous Vue project. Sure enough, axios is still nicer to use~
(Though if we turn it into a mini program later, we'll probably still need to refactor. I hear mini programs don't support formdata)
Wrapping useState
Thanks to "frontend mentor coppy" for providing this code~
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
};
});
}
];
}
This way you don't need to add ...state every time you setState.
Before:
import {useState} from 'react'
export const LoginPage = observer(() => {
const [state, setState] = useState({
username: '',
password: '',
})
setState({
...state,
username: '', password: ''
})
}
After:
import useYourState from "@/utils/coppy_state";
export const LoginPage = observer(() => {
const [state, setState] = useYourState({
username: '',
password: '',
})
setState({
username: '', password: ''
})
}
Productivity went up~
Global State Management
I didn't go with the famous Redux, and instead used the relatively simpler MobX.
But the example docs I found weren't great (for example, the official Chinese docs: https://cn.mobx.js.org/)
In the end I still sought help from my "frontend mentor" and got it working.
Pitfalls:
- Stores can no longer use decorators now; use this
makeAutoObservable - No need for a global provider
- The Taro official site and examples are arguably the biggest trap in history. Don't get fooled. URL: https://taro-docs.jd.com/taro/docs/mobx/
- Please use the latest versions of MobX and
mobx-react-lite. Don't use the 4.8 version on the Taro official site—it's too old and useless
Code
No need to wrap with a global provider anymore. Just use a global variable. Of course you can also use React Context.
Store definition
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()
Component usage
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
References
- Official docs: https://mobx.js.org/react-integration.html
- Project URL: https://github.com/mobxjs/mobx/tree/main/packages/mobx-react
- MobX React Beginner's Guide (Juejin): https://juejin.cn/post/6844903831726211079
- Using MobX in React with class components, function components, and hooks: https://juejin.cn/post/6873794258743066632#heading-2
Deserializing JSON to a Class
Use this library: https://github.com/typestack/class-transformer
Model definition. This definition can be generated from JSON. There are many online tools, for example: https://apihelper.jccore.cn/jsontool
export class User {
username: string
first_name: string
last_name: string
email: string
date_joined: string
}
Note that the docs on the project homepage are also outdated. The plainToClass method is deprecated; you need to use this method: plainToInstance
import {plainToInstance} from "class-transformer";
const user = plainToInstance(User, res.data.user)
myUserStore.login(user, res.data.token)
_EOF_
Notes on React + TypeScript + Taro Frontend Development
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
视频中台解决方案:组织树组件+多路视频直播界面开发
这种国产粗犷风格的项目居然能用?16路视频播放界面倒是简单直接,但现场配置和设备管理流程真是够折腾的。WVP和mpegts.js?B站开源的尿性,细节全靠蒙。
2025-07-04 · Web前端 · 约 1 分钟
在TypeScript项目中搭配Axios封装后端接口调用
封装axios?TypeScript下不过是加些类型声明,真当创新了。拦截器自动加token和401跳转,标准操作而已。统一返回值?又是后端那套,麻烦。
2024-01-24 · Web前端 · 约 1 分钟
NextJs 与 Tailwind 入门开发笔记
Next.js?React的脚手架罢了,开箱即用,拒绝精神内耗。Tailwind?Bootstrap的替代品,罢了。实际开发中,pnym坑死人,localStorage问题?小菜一碟。
2024-01-27 · Web前端 · 约 1 分钟
魔改了一下bootstrap-treeview组件,发布个NPM包体验一下
前言 之前在这篇文章 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示 中说到,我为了让文章分类列表支持层级结构,用了一个树形组件,不过这个组件太老了,使用的Bootstrap版本居然是3.x的,但又找不到更好的,只能硬着头皮用。 但实际效果有很多我不满意的,人家作者直接放弃了,在GitHub上标记项目为Archive状态,没辙。 感谢开源,我直接fork一份代码来
2022-05-27 · Web前端 · 约 1 分钟
讨论
共 0 条加载评论中…