此篇接上篇文章: 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… 有问题欢迎加群沟通哦: