創(chuàng)建React16.6,Mobx5 和 Typescript3 初始工程

    Getting started with MOBX 5 and TypeScript 3, React 16.6

    原文為一篇英文文章,整篇幾乎不用翻譯即可看懂,這里只做簡(jiǎn)要注解,轉(zhuǎn)載信息見(jiàn)文末。愛(ài)掏網(wǎng) - it200.com


    When looking around for example applications that use Mobx 5.x combined with Mobx-react 5.xand TypeScript 3.x I did not find any useful example. Most of the examples in the awesome mobx list reference Mobx 3.x and are really outdated.


    你沒(méi)理解錯(cuò),作者只是想找一個(gè)example,很可惜要么找不到要么是過(guò)時(shí)的,只能自己造了。愛(ài)掏網(wǎng) - it200.com


    In my example I will use MOBX to display “Hello World!”. It should showcase a couple of core concepts you will be using in an mobx application.


    使用mobx做一個(gè)Hello World! 示例程序,同時(shí)講解了使用mobx的一些核心概念


    tl:dr: Source Code for this example can be found here.


    源代碼所在地 here

    Inititalizing the project


    First we need to create our project. I will use following scripts to intitialize the project.


    Create-react-app with TypeScript

    npx create-react-app mobx-example
    cd mobx-example
    npm install --save typescript @types/node @types/react @types/react-dom @types/jest
    
    npx mv 'src/App.js' 'src/App.tsx' 
    npx mv 'src/App.test.js' 'src/App.test.tsx' 
    npx mv 'src/index.js' 'src/index.tsx'
    
    npm start

    補(bǔ)充:create-react-app@2.1.1中可以直接通過(guò)以下兩種方式直接創(chuàng)建ts工程

    1. create-react-app myApp --typescript
    2. create-react-app myApp --scripts-version=react-scripts-ts

    2.1.1以下版本未經(jīng)測(cè)試


    Note: I am using the npm package ‘mv’ to rename the files, this ensures that the script will work cross-plattform.

    We need to run start in order to let create-react-app initalize all typescript configuration files.


    MOBX

    npm install --save mobx mobx-react

    In the tsconfig.json you need to ensure that experimental Decorators are enabled. Add following line to your tsconfig:

    "experimentalDecorators": true

    啟用裝飾器,便可以進(jìn)行如下方式的開(kāi)發(fā)

    @observable // 使用裝飾器
    public name: string = 'world';

    Getting Started with MOBX


    In order to use a MOBX Store you need to create a couple of things:

    • A Mobx Store
    • Configure the provider
    • Use the store in a component

    使用mobx之前,需要對(duì)mobx進(jìn)行一些配置

    The Mobx Store

    Store Directory


    It is advisable to keep your stores organized in a single directory like ‘src/stores’.
    mkdir src/stores


    推薦開(kāi)發(fā)時(shí)為mobx store單獨(dú)創(chuàng)建一個(gè)文件夾

    The Example Store


    From the offical documentation to create a store it would be enough to create a class as follows:


    如果按照mobx的官方文檔來(lái),那么使用class來(lái)創(chuàng)建一個(gè)store,這樣就足夠了,如下:

    mobxStore.ts:
    import {observable, action, computed} from 'mobx';
    
    class MobxStore {
        @observable name = "World";
    
        @computed 
        public get greeting():string {
            return `Hello ${this.name}`;
        }
    
        @action.bound
        public setName(name:string):void {
            this.name = name;
        }
    }
    
    export mobxStore = new MobxStore();

    Note: Using @computed is just a demonstration how you could create a calculated value from the current state.


    使用@computed只是用來(lái)示范如何創(chuàng)建計(jì)算屬性的


    When using TypeScript this is not be enough, you need to create an interface and let our Store implement it to ensure type safety in the react component.


    問(wèn)題來(lái)了,當(dāng)在ts中使用時(shí)這樣做是不夠的,需要?jiǎng)?chuàng)建接口以便我們?cè)诮M件中使用時(shí)確保類型安全

    export interface IMobxStore { // 導(dǎo)出接口聲明,組件中使用store時(shí)要用
        name: string;
        greeting: string;
        setName(name:string):void;
    }

    Additionally we will move the initialization to its own class.

    Finally our mobxStore.ts looks like this:


    接口配置完就變成下面這樣了

    import {observable, action, computed} from 'mobx';
    
    export interface IMobxStore {
        name: string;
        greeting: string;
        setName(name:string):void;
    }
    
    export class MobxStore implements IMobxStore {
        @observable name = "World";
    
        @computed 
        public get greeting():string {
            return `Hello ${this.name}`;
        }
    
        @action.bound
        public setName(name:string):void {
            this.name = name;
        }
    }

    Note: The interface could also be moved into a type definition file.


    接口聲明可以統(tǒng)一放在一個(gè)單獨(dú)的類型定義文件中,方便統(tǒng)一管理,當(dāng)然不做強(qiáng)制要求

    Store initialization


    We will now create a file src/stores/index.tsIn this file we will create an object ‘stores’ that will initialize all stores that we are using in our application.


    src/stores/index.ts中統(tǒng)一導(dǎo)出所有的store

    index.ts:

    import { MobxStore } from "./mobxStore";
    
    export const stores = {
        mobxStore: new MobxStore()
    }

    Configuring the Provider


    Since we are ensuring that all stores are inititalized in a single object the configuration of the Provider is very simple In the file src/index.tsx you need to import the store object and the Provider from mobx-react:

    import {Provider} from 'mobx-react';
    import { stores } from './stores';

    Then you need to wrap the around the . By using the spread operator for stores you ensure that all stores are registered in the provider.


    store初始化完畢,然后在根組件中通過(guò)Provider注入store

    Using the Store


    In order to use a store in a component you need to inject the store into the component and (most of the time) you will also want to observe the store for changes.


    使用之前先通過(guò)mobx-react中提供的 inject方法注入store,如果需要在store中值發(fā)生變化的時(shí)候自動(dòng)更新組件,那么也需要添加observer,其實(shí)大部分時(shí)候都是需要監(jiān)聽(tīng)store的變化的。愛(ài)掏網(wǎng) - it200.com


    The store will be accessable via the properties. Thus we need to define an interface containing an optional variable ‘mobxStore’ of the type IMobxStore. It needs to be optional due to TypeScript not knowing that the Store is provided by the inject method. If it would be mandatory TypeScript would throw an missing props error when using .


    inject注入進(jìn)來(lái)的store通過(guò)props的方式進(jìn)行訪問(wèn),在那之前,需要先定義一個(gè)包含注入進(jìn)來(lái)mobxStore變量的接口,其中變量mobxStore的類型直接從mobxStore.ts中導(dǎo)入進(jìn)來(lái)即可。愛(ài)掏網(wǎng) - it200.com

    定義的接口中mobxStore變量是可選的,因?yàn)閠s無(wú)法檢測(cè)它被注入進(jìn)來(lái)。愛(ài)掏網(wǎng) - it200.com當(dāng)然這里雖然是可選的,但是實(shí)際使用的時(shí)候,它是一定存在的。愛(ài)掏網(wǎng) - it200.com這也是下文使用! 排除掉null 和 undefined的緣故。愛(ài)掏網(wǎng) - it200.com


    This in turn causes TypeScript to complain that const {greeting} = this.props.mobxStore; is not allowed, as this.props.mobxStore could be ‘undefined’. By adding the Non-null assertion operator ‘!’ you can signal the TypeScript compiler to ignore this warning.


    上面就!符號(hào)做了說(shuō)明

    App.tsx:

    import React, { Component } from 'react';
    import './App.css';
    import { observer, inject } from 'mobx-react';
    import { IMobxStore } from './stores/mobxStore';
    
    interface AppProps {
      mobxStore?: IMobxStore
    }
    
    @inject('mobxStore')
    @observer
    class App extends Component {
      render() {
        const {greeting} = this.props.mobxStore!;
    
        return (
          
            
    {greeting}
    ); } private clickHandler = () =>{ const {setName} = this.props.mobxStore!; setName("Bob"); } } export default App;

    Conclusion


    Now if you run the application you should now see a wonderful “Hello World!” greeting and by clicking on the button it changes to “Hello Bob!” using mobx and typescript.

    I hope this makes it a little simpler to get started with React, Mobx and TypeScript.

    If you are interested in the project files you can get them from GitHub https://github.com/borgfriend/typescript-react-mobx-example


    程序運(yùn)行成功,完結(jié)!

    轉(zhuǎn)載聲明
    Published by HappyNeal
    https://www.nealbuerger.com/2024/11/11/getting-started-with-mobx-5-and-typescript-3-react-16-6/

    聲明:所有內(nèi)容來(lái)自互聯(lián)網(wǎng)搜索結(jié)果,不保證100%準(zhǔn)確性,僅供參考。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。
    發(fā)表評(píng)論
    更多 網(wǎng)友評(píng)論0 條評(píng)論)
    暫無(wú)評(píng)論

    返回頂部

    主站蜘蛛池模板: 国产AV午夜精品一区二区三| 国产精品一区二区在线观看| 精品亚洲A∨无码一区二区三区| 亚洲熟妇成人精品一区| 亚洲爽爽一区二区三区| 日本精品视频一区二区| 中文字幕乱码一区久久麻豆樱花| 中文无码AV一区二区三区| 蜜桃臀无码内射一区二区三区| 色久综合网精品一区二区| 国模无码视频一区| 精品乱人伦一区二区三区| 无码人妻精品一区二| 色婷婷亚洲一区二区三区| 中文字幕日韩一区二区不卡| 日韩精品一区二区亚洲AV观看| 国产综合精品一区二区三区| 中文字幕久久久久一区| 日韩综合无码一区二区| 精品视频一区二区三区在线播放| 国产一区二区三区小说| 无码喷水一区二区浪潮AV| 亚洲av乱码中文一区二区三区| 精品国产a∨无码一区二区三区| 人妻体内射精一区二区三区| 制服丝袜一区在线| 麻豆AV无码精品一区二区| 国产一区二区三区韩国女主播| 国产韩国精品一区二区三区久久| 亚洲男女一区二区三区| 国产日韩一区二区三区在线播放| 精品国产AV一区二区三区| 亚洲av日韩综合一区久热| 日韩高清一区二区三区不卡| 日韩精品无码久久一区二区三| 日本一区二区三区在线网| 影院无码人妻精品一区二区| 国模大尺度视频一区二区| 日韩欧美一区二区三区免费观看 | 日韩精品一区二区三区国语自制 | 一区二区三区免费高清视频|