Electron+react+mobx

此篇接上篇文章: Electron-從零到一搭建-編寫基礎看框架javascript

這篇文章主要在此基礎上來集成ReactMobx, 你們先拉取下上篇demo: github.com/spcBackToLi…java

集成React

主要方式就是將本身寫的react組件綁到一個dom元素上。修改render-process中的index.tsx。 添加一下React基礎依賴:react

yarn add react react-dom -D
複製代碼

首先,在render-process下新建pages文件夾,並新建pages/index.tsx文件用於放置咱們的react頁面組件,咱們寫入一個react組件git

import React from 'react';
export const App = () => {
  return (<div> hello </div>);
}
複製代碼

再在render-process/index.tsx中將react組件綁定到dom上。github

import ReactDOM from 'react-dom';
import { App } from './pages/index';

ReactDOM.render(
  App(),
  document.getElementById('root')
);

複製代碼

運行一下,發現沒法識別index.tsx裏的react組件語法,此時須要裝一個@babel/preset-react插件就好:typescript

yarn add @babel/preset-react -D
複製代碼

集成mobx

不熟悉mobx的,能夠先看看個人另外一篇Mobx 基礎, 在react中集成mobx分四步:bash

  • 新建一個stores文件夾,下面共用的store,每一個store存儲: 狀態改變狀態的動做(Action)計算值reaction(反饋)等。
  • 使用mobx-react中的Provider包裹react根組件,讓你能夠把傳遞下來的store做用在react提供的上下文機制。
  • 在相關組件上使用inject注入想要的狀態store,及相關內容,在組件對應文件夾下寫相應的store文件。
  • 在具備狀態的組件上使用observer, 若是有使用的狀態發生變化,則更新該組件。

接下來就是具體demo, demo中也會實驗一些特性展現給你們,最後戶總結一些東西的使用特色。babel

  1. render-process/pages下新建mobx-demo文件夾,新建mobx-demo/demo-store.ts。 mobx-demo/demo-store.ts 先安裝下mobx依賴:
yarn add mobx -D
複製代碼
import { observable, action, configure, computed, autorun } from 'mobx';
// 作一些全局配置,好比: enforceActions,表示此store種更改狀態必須使用action
configure({
  enforceActions: true,
  computedConfigurable: false,
});

class DemoStore {
  @observable count = 0; // 定義一個狀態變化量,給他@observable檢測上。

  @observable test = 1;

  @action // 定義一個改變狀態的action
  changeCount = () => {
    console.log('改變count');
    this.count++;
  }

  @action // 定義一個改變狀態的action
  changeTest = () => {
    console.log('改變test');
    this.test++;
  }

  @computed get cc() { // 定義計算值:若是相關屬性count 變化了,且這個屬性被使用了,則會調用此函數計算。
    console.log('屬性變化了,執行此函數-cc');
    return this.count + 2;
  }

  @computed get bb() { // 分析測試代碼
    console.log('屬性變化了,執行此函數-bb');
    return this.count + 2;
  }
}

export const demoStore = new DemoStore();

autorun(() => {
  // 在autorun裏用到了哪一個變量,若是他變化了,則會自動執行一次autorun
  console.log('demoStore-count:', demoStore.count);
});

autorun(() => {
  // 在autorun裏用到了哪一個變量,若是他變化了,則會自動執行一次autorun
  console.log('demoStore-test:', demoStore.test);
});

複製代碼
  1. render-process中新建stores文件夾,新建store.ts, 導入全部store
// 用於定義全部的store
import { demoStore } from '../pages/mobx-demo/demo-store';

export const stores = {
  demoStore,
};

複製代碼

render-process/pages/index.tsx,react組件入口處使用Provider包裹組件,傳入storereact-router

yarn add react-router-dom -D
複製代碼
import React from 'react';
import { Provider } from 'mobx-react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Demo } from './mobx-demo/index';
import { stores } from '../stores/stores';

export function App() {
  return (
    <Provider {...stores}> <Router> <div> <Route path="/" component={Demo} /> </div> </Router> </Provider> ); } 複製代碼
  1. 新建組件mobx-demo/index.tsx,並在組件上注入須要的狀態store:
yarn add mobx-react -D
複製代碼

mobx-demo/index.tsx框架

import React, { PureComponent } from 'react';
  import { inject, observer } from 'mobx-react';

  @inject('demoStore')
  @observer
  export class Demo extends PureComponent<any, any> {
    render() {
      return (
        <div> Demo-cc: {this.props.demoStore.cc} <button onClick={this.props.demoStore.changeCount}>改變count</button> <br/> Demo-bb: {this.props.demoStore.bb} <button onClick={this.props.demoStore.changeTest}>改變Test</button> </div>
      );
    }
  }
複製代碼

ps: 若是vscode編輯器出現Property 'props' does not exist on type Home問題,由於ts語法識別問題,咱們使用了react,因此安裝下type依賴識別語法。咱們須要配置下:

yarn add @types/react -D
複製代碼
  1. 至此,mobx集成完畢,可是運行仍是會報錯,由於咱們使用了裝飾器,可是並無在Babel中處理此語法, 一樣還會有ts語法報錯,也須要ts的配置,所以,咱們須要添加babel配置。
yarn add @babel/preset-typescript @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
複製代碼

.babelrc 改成:

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "useBuiltIns": "entry",
          "modules": false
        }
      ],
      ["@babel/preset-react"],
      ["@babel/preset-typescript"]
    ],
    "plugins": [
      "@babel/plugin-syntax-dynamic-import",
      "@babel/plugin-transform-runtime",
      ["@babel/plugin-proposal-decorators", {"legacy": true}], // 用於裝飾器,先 proposal-decorators 再 proposal-class-properties
      ["@babel/plugin-proposal-class-properties", { "loose": true }] // 用於裝飾器
    ]
  }
複製代碼
  1. 咱們運行demo: yarn dev 會有以下結論: 初次加載:
    • 初次加載demoStore時,被@observable的變量被賦值,相應用到改變量的autorun函數也會被執行。
    • 頁面上被用到的@computed標記的計算值,會計算一次。

咱們點擊改變count的action時候, 發現: - changeCount action被執行, cc, bb計算值方法被從新計算 - 用到count狀態的autorun被執行(不管頁面是否用到count變量, 只要改變,都會執行),未用到此countautorun未被執行。

咱們先屏蔽掉頁面中的bb計算值的使用: ```javascript import React, { PureComponent } from 'react'; import { inject, observer } from 'mobx-react';

@inject('demoStore')
@observer
export class Demo extends PureComponent<any, any> {
  render() {
    return (
      <div>
        Demo-cc:
        {this.props.demoStore.cc}
        <button onClick={this.props.demoStore.changeCount}>改變count</button>
        <br/>
        <button onClick={this.props.demoStore.changeTest}>改變Test</button>
      </div>
    );
  }
}
```
咱們發現:
- `changeCount` action被執行, `cc`計算值方法被從新計算,與`cc`一樣和`count`狀態相關的`bb`並無被執行,由於`bb`沒被使用。

咱們再點擊`改變Test`按鈕,發現:
- 執行了`changeTest`Action,執行了相關的`autorun`
複製代碼

總結: - 改變變量的時候,建議使用Action去觸發改變,如demo中的changeCount - autorun執行的函數中用到的被@observable的變量改變時候則會執行一次此函數,不管變量是否被頁面使用。 - @computed的計算值相關的狀態值改變的時候,只有此計算值在頁面中使用時纔會從新在計算運行一次,不然再也不從新計算。

此篇demo: github.com/spcBackToLi… 有問題歡迎加羣溝通哦:

羣
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息