Getting started with MOBX 5 and TypeScript 3, React 16.6
原文為一篇英文文章,整篇幾乎不用翻譯即可看懂,這里只做簡要注解,轉載信息見文末。愛掏網 - 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.
你沒理解錯,作者只是想找一個example
,很可惜要么找不到要么是過時的,只能自己造了。愛掏網 - 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
做一個Hello World!
示例程序,同時講解了使用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
補充:create-react-app@2.1.1
中可以直接通過以下兩種方式直接創建ts工程
create-react-app myApp --typescript
create-react-app myApp --scripts-version=react-scripts-ts
2.1.1
以下版本未經測試
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
啟用裝飾器,便可以進行如下方式的開發
@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之前,需要對mobx進行一些配置
The Mobx Store
Store Directory
It is advisable to keep your stores organized in a single directory like ‘src/stores’.mkdir src/stores
推薦開發時為mobx store
單獨創建一個文件夾
The Example Store
From the offical documentation to create a store it would be enough to create a class as follows:
如果按照mobx的官方文檔來,那么使用class
來創建一個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
只是用來示范如何創建計算屬性的
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.
問題來了,當在ts
中使用時這樣做是不夠的,需要創建接口以便我們在組件中使用時確保類型安全
export interface IMobxStore { // 導出接口聲明,組件中使用store時要用 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.
接口聲明可以統一放在一個單獨的類型定義文件中,方便統一管理,當然不做強制要求
Store initialization
We will now create a file src/stores/index.ts
In this file we will create an object ‘stores’ that will initialize all stores that we are using in our application.
在src/stores/index.ts
中統一導出所有的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
store
初始化完畢,然后在根組件中通過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.
使用之前先通過mobx-react中提供的 inject方法注入store
,如果需要在store中值發生變化的時候自動更新組件,那么也需要添加observer
,其實大部分時候都是需要監聽store的變化的。愛掏網 - 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
注入進來的store
通過props
的方式進行訪問,在那之前,需要先定義一個包含
注入進來mobxStore
變量的接口,其中變量mobxStore
的類型直接從mobxStore.ts
中導入進來即可。愛掏網 - it200.com
定義的接口中mobxStore
變量是可選的,因為ts無法檢測它被注入進來。愛掏網 - it200.com當然這里雖然是可選的,但是實際使用的時候,它是一定存在的。愛掏網 - it200.com這也是下文使用! 排除掉null 和 undefined
的緣故。愛掏網 - 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.
上面就!
符號做了說明
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
程序運行成功,完結!
轉載聲明
Published by HappyNeal
https://www.nealbuerger.com/2024/11/11/getting-started-with-mobx-5-and-typescript-3-react-16-6/