国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React結(jié)合TypeScript和Mobx初體驗(yàn)

dreambei / 1572人閱讀

摘要:結(jié)合編輯器可以推導(dǎo)變量對應(yīng)的類型以及內(nèi)部的結(jié)構(gòu),提高代碼的健壯性和可維護(hù)性。通過充分利用時(shí)間回溯的特征,可以增強(qiáng)業(yè)務(wù)的可預(yù)測性與錯(cuò)誤定位能力。對于對象的哪部分需要成為可觀察的,提供了細(xì)粒度的控制。

為什么要使用TypeScript 偵測錯(cuò)誤

通過靜態(tài)類型檢測可以盡早檢測出程序中隱藏的的邏輯錯(cuò)誤,對于JavaScript動(dòng)態(tài)的弱類型語言,雖然靈活性高,但是對于初學(xué)者來說,如果不熟悉JavaScript內(nèi)部的語言機(jī)制,很容易造成隱藏的事故。但是通過TypeScript的靜態(tài)類型檢測可以規(guī)避這些問題,因?yàn)槠淠軌蚣s束變量產(chǎn)生的類型。結(jié)合IDE編輯器可以推導(dǎo)變量對應(yīng)的類型以及內(nèi)部的結(jié)構(gòu),提高代碼的健壯性和可維護(hù)性。

抽象

類型系統(tǒng)能夠強(qiáng)化規(guī)范編程,TypeScript提供定義接口。在開發(fā)大型復(fù)雜的應(yīng)用軟件時(shí)十分重要,一個(gè)系統(tǒng)模塊可以抽象的看做一個(gè)TypeScript定義的接口。讓設(shè)計(jì)脫離實(shí)現(xiàn),最終體現(xiàn)出一種 IDL(接口定義語言,Interface Define Language),讓程序設(shè)計(jì)回歸本質(zhì)。

文檔

TypeScript可以自動(dòng)根據(jù)類型標(biāo)注生成文檔,對于簡單的功能實(shí)現(xiàn)都不需要編寫注釋。

為什么要使用Mobx MobX 和 Redux 的比較

先要明白 mobx 和 redux 的定位是不同的。redux 管理的是 (STORE -> VIEW -> ACTION) 的整個(gè)閉環(huán),而 mobx 只關(guān)心 STORE -> VIEW 的部分。

Redux優(yōu)缺點(diǎn):

數(shù)據(jù)流流動(dòng)很自然,因?yàn)槿魏?dispatch 都會觸發(fā)廣播,依據(jù)對象引用是否變化來控制更新粒度。

通過充分利用時(shí)間回溯的特征,可以增強(qiáng)業(yè)務(wù)的可預(yù)測性與錯(cuò)誤定位能力。

時(shí)間回溯代價(jià)高,因?yàn)槊看味家乱茫窃黾哟a復(fù)雜度,或使用 immutable。

時(shí)間回溯的另一個(gè)代價(jià)是 action 與 reducer 完全脫節(jié),原因是可回溯必然不能保證引用關(guān)系。

引入中間件,解決異步帶來的副作用,業(yè)務(wù)邏輯或多或少參雜著 magic。

靈活利用中間件,可以通過約定完成許多復(fù)雜的工作。

對 typescript 支持困難。

Mobx優(yōu)缺點(diǎn):

數(shù)據(jù)流流動(dòng)不自然,只有用到的數(shù)據(jù)才會引發(fā)綁定,局部精確更新,但避免了粒度控制煩惱。

沒有時(shí)間回溯能力,因?yàn)閿?shù)據(jù)只有一份引用。自始至終一份引用,不需要 immutable,也沒有復(fù)制對象的額外開銷。

數(shù)據(jù)流動(dòng)由函數(shù)調(diào)用一氣呵成,便于調(diào)試。

業(yè)務(wù)開發(fā)不是腦力活,而是體力活,少一些 magic,多一些效率。

由于沒有 magic,所以沒有中間件機(jī)制,沒法通過 magic 加快工作效率(這里 magic 是指 action 分發(fā)到 reducer 的過程)。

完美支持 typescript。

SO: 前端數(shù)據(jù)流不太復(fù)雜的情況,使用 Mobx,因?yàn)楦忧逦脖阌诰S護(hù);如果前端數(shù)據(jù)流極度復(fù)雜,建議謹(jǐn)慎使用 Redux,通過中間件減緩巨大業(yè)務(wù)復(fù)雜度

使用Create-React-App來建立TypeScript的環(huán)境
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: 最后一個(gè)命令使用eject將所有內(nèi)建的配置暴露出來

通過create-react-app可以很方便地對整個(gè)項(xiàng)目完成環(huán)境初始化,如果愿意折騰TypeScript和webpack的環(huán)境可以試試,這里忽略webpack和TypeScript的環(huán)境搭建過程,而是使用create-react-app來實(shí)現(xiàn)環(huán)境搭建。

加入React-Router

單頁應(yīng)用怎么可以沒有前端路由呢,所以我們要加入React-Rotuer, 這里使用的React-Router的版本是v4.2.0

路由配置使用姿勢

對于React-Router,這里使用到的模塊有Router, Route, Switch

React Router 是建立在 history 之上的。 簡而言之,一個(gè) history 知道如何去監(jiān)聽瀏覽器地址欄的變化, 并解析這個(gè) URL 轉(zhuǎn)化為 location 對象, 然后 router 使用它匹配到路由,最后正確地渲染對應(yīng)的組件。

代碼如下:

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這個(gè)組件的編寫

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";

// 這部分是坑點(diǎn),一開始不知道配置,后發(fā)現(xiàn)react-rotuer的4.0版本下需要配置prop的接口
interface Container extends RouteComponentProps<{}> {
}

class Container extends React.Component {
  render () {
    return (
      
) } } export default Container;

這樣,當(dāng)我們訪問url為"/"的時(shí)候,默認(rèn)會進(jìn)入Container,其中Container里面是一層子頁面,會匹配url,如果url為"/website", 則進(jìn)入Website頁面,若為"/",則進(jìn)入App頁面。

具體關(guān)于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來進(jìn)行數(shù)據(jù)狀態(tài)的管理
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的嚴(yán)格模式,規(guī)范數(shù)據(jù)修改操作只能在action中進(jìn)行
useStrict(true);

const browserHistory = createBrowserHistory();
const routerStore =  new RouterStore();
// 同步路由與mobx的數(shù)據(jù)狀態(tài)
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(
  
    
      
        
          
          
          
        
      
    
  ,
  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來進(jìn)行數(shù)據(jù)監(jiān)聽和數(shù)據(jù)依賴聲明
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 可以在實(shí)例字段和屬性 getter 上使用。 對于對象的哪部分需要成為可觀察的,@observable 提供了細(xì)粒度的控制。

@inject 相當(dāng)于Provider 的高階組件。可以用來從 React 的context中挑選 store 作為 prop 傳遞給目標(biāo)組件

組件的接口定義
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";

// 路由狀態(tài)同步
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";

// 登錄注冊狀態(tài)
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是用于網(wǎng)站的登錄注冊事件以及對應(yīng)的Token的數(shù)據(jù)狀態(tài)保存,登錄注冊事件的接口請求等操作。

具體的有關(guān)Mobx的用法請閱讀Mobx文檔

目錄結(jié)構(gòu)
app
├── api             后端提供的接口數(shù)據(jù)請求
├── components      編寫的可復(fù)用組件
├── config          側(cè)邊欄以及導(dǎo)航欄配置
├── constants       常量編寫
├── interfaces      接口編寫
├── layout          布局外框
├── stores          mobx的數(shù)據(jù)狀態(tài)管理
├── index.css       全局樣式
├── index.tsx       頁面入口
├── reset.css       瀏覽器重置樣式

本項(xiàng)目使用了Ant-Design來作為依賴的組件庫,具體怎么使用以及配置請參考Ant-Design

到這里其實(shí)以及完成對React下TypeScript結(jié)合React-Router和Mobx的配置。具體的業(yè)務(wù)模塊如何編寫有興趣可以參閱項(xiàng)目tinylog-ui

個(gè)人表達(dá)能力有限,無法描述得太清晰,請見諒!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95221.html

相關(guān)文章

  • 我理想中的狀態(tài)管理工具

    摘要:現(xiàn)已存在許多成熟的狀態(tài)管理解決方案,還有基于的但對于我個(gè)人來說,理想的狀態(tài)管理工具只需同時(shí)滿足兩個(gè)特點(diǎn)簡單易用,并且適合中大型項(xiàng)目完美地支持要做到這兩點(diǎn)其實(shí)并不簡單。所以我決定自己造一個(gè)可能是基于和最好的狀態(tài)管理工具 現(xiàn)已存在許多成熟的狀態(tài)管理解決方案:Redux、Mobx、Mobx-state-tree,還有基于 Redux 的 Dva.js、Rematch... 但對于我個(gè)人來說,...

    roadtogeek 評論0 收藏0
  • 前端每周清單第 45 期: Safari 支持 Service Worker, Parcel 完整教

    摘要:的另一個(gè)核心特性,蘋果表示也正在開發(fā)中,按開發(fā)進(jìn)度可能幾個(gè)月后就能與我們見面。是基于的本地化數(shù)據(jù)庫,支持以及瀏覽器環(huán)境。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(ID: frontshow),及時(shí)獲取前端每周清單。 本期是 2017 年的最后一...

    趙春朋 評論0 收藏0
  • React+TypeScript+Mobx+AntDesignMobile進(jìn)行移動(dòng)端項(xiàng)目搭建

    摘要:通過裝飾器或者利用時(shí)調(diào)用的函數(shù)來進(jìn)行使用下面代碼中當(dāng)或者發(fā)生變化時(shí),會監(jiān)聽數(shù)據(jù)變化確保通過觸發(fā)方法自動(dòng)更新。只能影響正在運(yùn)行的函數(shù),而無法影響當(dāng)前函數(shù)調(diào)用的異步操作參考官方文檔用法裝飾器函數(shù)遵循中標(biāo)準(zhǔn)的綁定規(guī)則。 前言: 本文基于React+TypeScript+Mobx+AntDesignMobile技術(shù)棧,使用Create-React-App腳手架進(jìn)行一個(gè)移動(dòng)端項(xiàng)目搭建,主要介紹項(xiàng)...

    lindroid 評論0 收藏0
  • Electron 14.0.0 發(fā)布、StackBlitz 支持快速創(chuàng)建 Nuxt.js 應(yīng)用 |

    摘要:發(fā)布發(fā)布節(jié)奏變化從月份的開始,將每周發(fā)布一個(gè)新的穩(wěn)定版本。將于年月日開始測試,穩(wěn)定版將于年月日發(fā)布。一個(gè)使用和實(shí)現(xiàn)了個(gè)用戶界面的頁面。實(shí)踐總結(jié)是一個(gè)現(xiàn)代的企業(yè)級框架,提供了強(qiáng)大的和許多開箱即用的功能。 .markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x...

    Jensen 評論0 收藏0
  • Mobx + React Native 獲取路由的狀態(tài)信息

    摘要:年前公司由一個(gè)項(xiàng)目是使用來開發(fā)的所以遇到了一些問題比較影響開發(fā)進(jìn)程的就是路由問題了實(shí)際上就是這個(gè)組件比較難懂這里給大家講解一下希望大家少踩點(diǎn)坑另外本篇文章使用的是環(huán)境主要講解的還是如何使用記錄中路由的狀態(tài)但是會穿插一些小內(nèi)容這里雖然講到的是 年前公司由一個(gè)項(xiàng)目是使用 ReactNative 來開發(fā)的所以遇到了一些問題,比較影響開發(fā)進(jìn)程的就是路由問題了,實(shí)際上就是 ReactNaviga...

    李濤 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<