React结合TypeScript和Mobx步骤详解
这次给大家带来React结合TypeScript和Mobx步骤详解,React结合TypeScript和Mobx的注意事项有哪些,下面就是实战案例,一起来看一下。
为什么要使用TypeScript
侦测错误
通过静态类型检测可以尽早检测出程序中隐藏的的逻辑错误,对于JavaScript动态的弱类型语言,虽然灵活性高,但是对于初学者来说,如果不熟悉JavaScript内部的语言机制,很容易造成隐藏的事故。但是通过TypeScript的静态类型检测可以规避这些问题,因为其能够约束变量产生的类型。结合IDE编辑器可以推导变量对应的类型以及内部的结构,提高代码的健壮性和可维护性。
抽象
类型系统能够强化规范编程,TypeScript提供定义接口。在开发大型复杂的应用软件时十分重要,一个系统模块可以抽象的看做一个TypeScript定义的接口。让设计脱离实现,最终体现出一种 IDL(接口定义语言,Interface Define Language),让程序设计回归本质。
文档
TypeScript可以自动根据类型标注生成文档,对于简单的功能实现都不需要编写注释。
为什么要使用Mobx
MobX 和 Redux 的比较
先要明白 mobx 和 redux 的定位是不同的。redux 管理的是 (STORE -> VIEW -> ACTION) 的整个闭环,而 mobx 只关心 STORE -> VIEW 的部分。
Redux优缺点:
数据流流动很自然,因为任何 dispatch 都会触发广播,依据对象引用是否变化来控制更新粒度。
通过充分利用时间回溯的特征,可以增强业务的可预测性与错误定位能力。
时间回溯代价高,因为每次都要更新引用,除非增加代码复杂度,或使用 immutable。
时间回溯的另一个代价是 action 与 reducer 完全脱节,原因是可回溯必然不能保证引用关系。
引入中间件,解决异步带来的副作用,业务逻辑或多或少参杂着 magic。
灵活利用中间件,可以通过约定完成许多复杂的工作。
对 typescript 支持困难。
Mobx优缺点:
数据流流动不自然,只有用到的数据才会引发绑定,局部精确更新,但避免了粒度控制烦恼。
没有时间回溯能力,因为数据只有一份引用。自始至终一份引用,不需要 immutable,也没有复制对象的额外开销。
数据流动由函数调用一气呵成,便于调试。
业务开发不是脑力活,而是体力活,少一些 magic,多一些效率。
由于没有 magic,所以没有中间件机制,没法通过 magic 加快工作效率(这里 magic 是指 action 分发到 reducer 的过程)。
完美支持 typescript。
SO: 前端数据流不太复杂的情况,使用 Mobx,因为更加清晰,也便于维护;如果前端数据流极度复杂,建议谨慎使用 Redux,通过中间件减缓巨大业务复杂度
使用Create-React-App来建立TypeScript的环境
npm i -g create-react-app create-react-app tinylog-ui --scripts-version=react-scripts-ts cd tinylog-ui/ npm start npm run eject
TPS: 最后一个命令使用eject将所有内建的配置暴露出来
通过create-react-app可以很方便地对整个项目完成环境初始化,如果愿意折腾TypeScript和webpack的环境可以试试,这里忽略webpack和TypeScript的环境搭建过程,而是使用create-react-app来实现环境搭建。
加入React-Router
单页应用怎么可以没有前端路由呢,所以我们要加入React-Rotuer, 这里使用的React-Router的版本是v4.2.0
路由配置使用姿势
对于React-Router,这里使用到的模块有Router, Route, Switch
React Router 是建立在 history 之上的。 简而言之,一个 history 知道如何去监听浏览器地址栏的变化, 并解析这个 URL 转化为 location 对象, 然后 router 使用它匹配到路由,最后正确地渲染对应的组件。
代码如下:
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { Router, Route, Switch } from 'react-router'; import { createBrowserHistory } from 'history'; import registerServiceWorker from './registerServiceWorker'; import { Root } from './containers/Root'; import './index.css'; import Container from './containers/Container'; import SignIn from './containers/Auth/signIn'; import SignUp from './containers/Auth/signUp'; const history = createBrowserHistory(); ReactDOM.render( <Root> <Router history={history}> <Switch> <Route path="/signIn" component={SignIn} /> <Route path="/signUp" component={SignUp} /> <Route path="/" component={Container} /> </Switch> </Router> </Root>, document.getElementById('root') as HTMLElement ); registerServiceWorker();
页面的编写
这里描述一写Container这个组件的编写
import * as React from 'react'; import Header from '../../layout/Header'; import { IAuth } from '../../interfaces'; import { Route, Switch } from 'react-router'; import App from '../App'; import Website from '../Website'; // 这部分是坑点,一开始不知道配置,后发现react-rotuer的4.0版本下需要配置prop的接口 interface Container extends RouteComponentProps<{}> { } class Container extends React.Component<Container, {}> { render () { return ( <p> <Header {...this.props} /> <Switch> <Route path="/website" component={Website}/> <Route path="/" component={App}/> </Switch> </p> ) } } export default Container;
这样,当我们访问url为'/'的时候,默认会进入Container,其中Container里面是一层子页面,会匹配url,如果url为'/website', 则进入Website页面,若为'/',则进入App页面。
具体关于React-Router的使用请阅读React-Router文档
加入Mobx
npm i mobx react-mobx mobx-react-router -S
重新修改index.tsx的入口配置
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { Router, Route, Switch } from 'react-router'; import { createBrowserHistory } from 'history'; import { useStrict } from 'mobx'; import { Provider } from 'mobx-react'; import { RouterStore, syncHistoryWithStore } from 'mobx-react-router'; // 定义需要使用到的store来进行数据状态的管理 import { TokenStore, AuthStore, HostStore, OverViewStore, AssetsStore, CommonDataStore, PageStore, RealTimeStore } from './stores'; import registerServiceWorker from './registerServiceWorker'; import { Root } from './containers/Root'; import './index.css'; import Container from './containers/Container'; import SignIn from './containers/Auth/signIn'; import SignUp from './containers/Auth/signUp'; // 引入Echarts import './macarons'; import 'echarts/map/js/world'; // 开启mobx的严格模式,规范数据修改操作只能在action中进行 useStrict(true); const browserHistory = createBrowserHistory(); const routerStore = new RouterStore(); // 同步路由与mobx的数据状态 const history = syncHistoryWithStore(browserHistory, routerStore); const rootStore = { token: new TokenStore(), auth: new AuthStore(), host: new HostStore(), overview: new OverViewStore(), assets: new AssetsStore(), commmon: new CommonDataStore(), page: new PageStore(), realtime: new RealTimeStore(), router: routerStore }; ReactDOM.render( <Provider {...rootStore}> <Root> <Router history={history}> <Switch> <Route path="/signIn" component={SignIn} /> <Route path="/signUp" component={SignUp} /> <Route path="/" component={Container} /> </Switch> </Router> </Root> </Provider>, document.getElementById('root') as HTMLElement ); registerServiceWorker();
Container容器的修改
import * as React from 'react'; import Header from '../../layout/Header'; import { IAuth } from '../../interfaces'; import { Route, Switch } from 'react-router'; // 使用inject和observer来进行数据监听和数据依赖声明 import { inject, observer } from 'mobx-react'; import App from '../App'; import Website from '../Website'; interface Container extends IAuth { } @inject('router', 'auth') @observer class Container extends React.Component<Container, {}> { render () { return ( <p> <Header {...this.props} /> <Switch> <Route path="/website" component={Website}/> <Route path="/" component={App}/> </Switch> </p> ) } } export default Container;
@observable 可以在实例字段和属性 getter 上使用。 对于对象的哪部分需要成为可观察的,@observable 提供了细粒度的控制。@inject 相当于Provider 的高阶组件。可以用来从 React 的context中挑选 store 作为 prop 传递给目标组件
组件的接口定义
import { RouteComponentProps } from 'react-router'; import { RouterStore, AuthStore } from '../stores'; export interface IBase extends RouteComponentProps<{}> { router: RouterStore; } export interface IAuth extends IBase { auth: AuthStore; }
Store的配置
先看一下RouterStore:
import { History } from 'history'; import { RouterStore as BaseRouterStore, syncHistoryWithStore } from 'mobx-react-router'; // 路由状态同步 class RouterStore extends BaseRouterStore { public history; constructor(history?: History) { super(); if (history) { this.history = syncHistoryWithStore(history, this); } } } export default RouterStore;
然后是AuthStore:
import { ISignIn, ISignUp } from './../interfaces/index'; import { observable, action } from 'mobx'; import api from '../api/auth'; import { IUser } from '../models'; // 登录注册状态 class AuthStore { @observable token; @observable id; @observable email; constructor () { this.id = ''; this.token = ''; this.email = ''; } setLocalStorage ({ id, token, email }: IUser) { localStorage.setItem('id', id); localStorage.setItem('token', token); localStorage.setItem('email', email); } clearStorage () { localStorage.clear(); } @action async signIn (data: ISignIn) { try { const { data: res } = await api.signIn(data); this.id = res.data.id; this.token = res.data.token; this.email = res.data.email; this.setLocalStorage({ id: this.id, token: this.token, email: this.email }); return res; } catch (error) { return error; } } @action async signUp (data: ISignUp) { try { const { data: res } = await api.signUp(data); this.id = res.data.id; this.token = res.data.token; this.email = res.data.email; this.setLocalStorage({ id: this.id, token: this.token, email: this.email }); return res; } catch (error) { return error; } } @action signOut () { this.id = ''; this.token = ''; this.email = ''; this.clearStorage() } } export default AuthStore;
Auth是用于网站的登录注册事件以及对应的Token的数据状态保存,登录注册事件的接口请求等操作。
具体的有关Mobx的用法请阅读Mobx文档
目录结构
app ├── api 后端提供的接口数据请求 ├── components 编写的可复用组件 ├── config 侧边栏以及导航栏配置 ├── constants 常量编写 ├── interfaces 接口编写 ├── layout 布局外框 ├── stores mobx的数据状态管理 ├── index.css 全局样式 ├── index.tsx 页面入口 ├── reset.css 浏览器重置样式
本项目使用了Ant-Design来作为依赖的组件库,具体怎么使用以及配置请参考Ant-Design
到这里其实以及完成对React下TypeScript结合React-Router和Mobx的配置。具体的业务模块如何编写有兴趣可以参阅项目tinylog-ui
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是React结合TypeScript和Mobx步骤详解的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

PHP、Vue和React:如何选择最适合的前端框架?随着互联网技术的不断发展,前端框架在Web开发中起着至关重要的作用。PHP、Vue和React作为三种具有代表性的前端框架,每一种都具有其独特的特点和优势。在选择使用哪种前端框架时,开发人员需要根据项目需求、团队技能和个人偏好做出明智的决策。本文将通过比较PHP、Vue和React这三种前端框架的特点和使

Java框架与React框架的整合:步骤:设置后端Java框架。创建项目结构。配置构建工具。创建React应用。编写RESTAPI端点。配置通信机制。实战案例(SpringBoot+React):Java代码:定义RESTfulAPI控制器。React代码:获取并显示API返回的数据。

Vue.js适合中小型项目和快速迭代,React适用于大型复杂应用。1)Vue.js易于上手,适用于团队经验不足或项目规模较小的情况。2)React的生态系统更丰富,适合有高性能需求和复杂功能需求的项目。

React通过JSX与HTML结合,提升用户体验。1)JSX嵌入HTML,使开发更直观。2)虚拟DOM机制优化性能,减少DOM操作。3)组件化管理UI,提高可维护性。4)状态管理和事件处理增强交互性。

React是构建交互式前端体验的首选工具。1)React通过组件化和虚拟DOM简化UI开发。2)组件分为函数组件和类组件,函数组件更简洁,类组件提供更多生命周期方法。3)React的工作原理依赖虚拟DOM和调和算法,提高性能。4)状态管理使用useState或this.state,生命周期方法如componentDidMount用于特定逻辑。5)基本用法包括创建组件和管理状态,高级用法涉及自定义钩子和性能优化。6)常见错误包括状态更新不当和性能问题,调试技巧包括使用ReactDevTools和优

NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVueDirectly.1)TeamExperience:selectBasedAsedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects,vueforsimplerprojects,reactforforforecomplexones.3)cocatizationNeedsneeds:reactofficatizationneedneeds:reactofferizationneedneedneedneeds:reactoffersizatization needeffersefersmoreflexiblesimore.4)ecosyaka

YBBCapitalResearcherAc-Core撰写:以太坊碎片化难题与OpenIntents框架:ERC-7683的破局之道图源:@ethereumfndnL2及DeFi的蓬勃发展,导致以太坊流动性碎片化日益严重。资产流动性分散于L1和众多L2,各平台间缺乏有效互联,如同一个个孤立的“小池子”,阻碍了以太坊整体效率。2024年,以太坊新增链条超过百条,这如同一个大型商场,商品琳琅满目,却需要使用不同货币结算。为解决这一问题,以太坊基金会于2月20日发布了OpenIntentsF

React生态系统包括状态管理库(如Redux)、路由库(如ReactRouter)、UI组件库(如Material-UI)、测试工具(如Jest)和构建工具(如Webpack)。这些工具协同工作,帮助开发者高效开发和维护应用,提高代码质量和开发效率。
