此篇接上篇文章: Electron-從零到一搭建-編寫基礎看框架javascript
這篇文章主要在此基礎上來集成React
、Mobx
, 你們先拉取下上篇demo: github.com/spcBackToLi…java
主要方式就是將本身寫的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
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);
});
複製代碼
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
包裹組件,傳入store
。react-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> ); } 複製代碼
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
複製代碼
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 }] // 用於裝飾器
]
}
複製代碼
yarn dev
會有以下結論: 初次加載:
demoStore
時,被@observable
的變量被賦值,相應用到改變量的autorun
函數也會被執行。@computed
標記的計算值,會計算一次。咱們點擊改變count
的action時候, 發現: - changeCount
action被執行, cc
, bb
計算值方法被從新計算 - 用到count
狀態的autorun
被執行(不管頁面是否用到count變量, 只要改變,都會執行),未用到此count
的autorun
未被執行。
咱們先屏蔽掉頁面中的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… 有問題歡迎加羣溝通哦: