摘要:結合編輯器可以推導變量對應的類型以及內部的結構,提高代碼的健壯性和可維護性。通過充分利用時間回溯的特征,可以增強業務的可預測性與錯誤定位能力。對于對象的哪部分需要成為可觀察的,提供了細粒度的控制。
為什么要使用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(頁面的編寫, 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{ render () { return ( ) } } export default Container;
這樣,當我們訪問url為"/"的時候,默認會進入Container,其中Container里面是一層子頁面,會匹配url,如果url為"/website", 則進入Website頁面,若為"/",則進入App頁面。
具體關于React-Router的使用請閱讀React-Router文檔
加入Mobxnpm 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(Container容器的修改, document.getElementById("root") as HTMLElement ); registerServiceWorker();
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{ render () { return ( ) } } 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
個人表達能力有限,無法描述得太清晰,請見諒!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95221.html
摘要:現已存在許多成熟的狀態管理解決方案,還有基于的但對于我個人來說,理想的狀態管理工具只需同時滿足兩個特點簡單易用,并且適合中大型項目完美地支持要做到這兩點其實并不簡單。所以我決定自己造一個可能是基于和最好的狀態管理工具 現已存在許多成熟的狀態管理解決方案:Redux、Mobx、Mobx-state-tree,還有基于 Redux 的 Dva.js、Rematch... 但對于我個人來說,...
摘要:的另一個核心特性,蘋果表示也正在開發中,按開發進度可能幾個月后就能與我們見面。是基于的本地化數據庫,支持以及瀏覽器環境。 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為新聞熱點、開發教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎關注【前端之巔】微信公眾號(ID: frontshow),及時獲取前端每周清單。 本期是 2017 年的最后一...
摘要:通過裝飾器或者利用時調用的函數來進行使用下面代碼中當或者發生變化時,會監聽數據變化確保通過觸發方法自動更新。只能影響正在運行的函數,而無法影響當前函數調用的異步操作參考官方文檔用法裝飾器函數遵循中標準的綁定規則。 前言: 本文基于React+TypeScript+Mobx+AntDesignMobile技術棧,使用Create-React-App腳手架進行一個移動端項目搭建,主要介紹項...
摘要:發布發布節奏變化從月份的開始,將每周發布一個新的穩定版本。將于年月日開始測試,穩定版將于年月日發布。一個使用和實現了個用戶界面的頁面。實踐總結是一個現代的企業級框架,提供了強大的和許多開箱即用的功能。 .markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x...
摘要:年前公司由一個項目是使用來開發的所以遇到了一些問題比較影響開發進程的就是路由問題了實際上就是這個組件比較難懂這里給大家講解一下希望大家少踩點坑另外本篇文章使用的是環境主要講解的還是如何使用記錄中路由的狀態但是會穿插一些小內容這里雖然講到的是 年前公司由一個項目是使用 ReactNative 來開發的所以遇到了一些問題,比較影響開發進程的就是路由問題了,實際上就是 ReactNaviga...
閱讀 1668·2021-11-23 10:07
閱讀 2664·2019-08-30 11:10
閱讀 2844·2019-08-29 17:08
閱讀 1787·2019-08-29 15:42
閱讀 3175·2019-08-29 12:57
閱讀 2402·2019-08-28 18:06
閱讀 3553·2019-08-27 10:56
閱讀 394·2019-08-26 11:33