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… 有问题欢迎加群沟通哦:

群
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息