Skip to content

Commit 787a25e

Browse files
committed
perf: prevent mobx state updates outside of actions
1 parent aa86abe commit 787a25e

File tree

5 files changed

+43
-26
lines changed

5 files changed

+43
-26
lines changed

app/src/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
3+
import { configure } from 'mobx';
34
import 'mobx-react-lite/batchingForReactDom';
45
import './i18n';
56
import './index.css';
@@ -8,6 +9,9 @@ import App from './App';
89

910
log.info('Rendering the App');
1011

12+
// ensure all state updates are made inside of an action
13+
configure({ enforceActions: 'observed' });
14+
1115
ReactDOM.render(
1216
<React.StrictMode>
1317
<App />

app/src/store/store.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { autorun, observable } from 'mobx';
1+
import { action, autorun, observable, runInAction } from 'mobx';
22
import { IS_DEV, IS_TEST } from 'config';
33
import AppStorage from 'util/appStorage';
44
import CsvExporter from 'util/csv';
@@ -65,30 +65,37 @@ export class Store {
6565
/**
6666
* load initial data to populate the store
6767
*/
68+
@action.bound
6869
async init() {
6970
this.settingsStore.init();
7071
await this.authStore.init();
71-
this.initialized = true;
72+
runInAction('init', () => {
73+
this.initialized = true;
74+
});
7275

7376
// this function will automatically run whenever the authenticated
7477
// flag is changed
75-
autorun(async () => {
76-
if (this.authStore.authenticated) {
77-
// go to the Loop page when the user is authenticated. it can be from
78-
// entering a password or from loading the credentials from storage
79-
this.uiStore.goToLoop();
80-
// also fetch all the data we need
81-
this.fetchAllData();
82-
} else {
83-
// go to auth page if we are not authenticated
84-
this.uiStore.gotoAuth();
85-
}
86-
});
78+
autorun(
79+
async () => {
80+
if (this.authStore.authenticated) {
81+
// go to the Loop page when the user is authenticated. it can be from
82+
// entering a password or from loading the credentials from storage
83+
this.uiStore.goToLoop();
84+
// also fetch all the data we need
85+
this.fetchAllData();
86+
} else {
87+
// go to auth page if we are not authenticated
88+
this.uiStore.gotoAuth();
89+
}
90+
},
91+
{ name: 'authenticatedAutorun' },
92+
);
8793
}
8894

8995
/**
9096
* makes the initial API calls to fetch the data we need to display in the app
9197
*/
98+
@action.bound
9299
async fetchAllData() {
93100
await this.nodeStore.fetchInfo();
94101
await this.channelStore.fetchChannels();

app/src/store/stores/authStore.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { action, observable } from 'mobx';
1+
import { action, observable, runInAction } from 'mobx';
22
import { prefixTranslation } from 'util/translate';
33
import { Store } from 'store';
44

@@ -59,8 +59,10 @@ export default class AuthStore {
5959
await this._store.api.lnd.getInfo();
6060
// if no error is thrown above then the credentials are valid
6161
this._store.log.info('authentication successful');
62-
// setting this to true will automatically show the Loop page
63-
this.authenticated = true;
62+
runInAction('validateContinuation', () => {
63+
// setting this to true will automatically show the Loop page
64+
this.authenticated = true;
65+
});
6466
}
6567

6668
/**

app/src/store/stores/settingsStore.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,18 @@ export default class SettingsStore {
5656
@action.bound
5757
init() {
5858
this.load();
59-
autorun(() => {
60-
const settings: PersistentSettings = {
61-
sidebarVisible: this.sidebarVisible,
62-
unit: this.unit,
63-
balanceMode: this.balanceMode,
64-
};
65-
this._store.storage.set('settings', settings);
66-
this._store.log.info('saved settings to localStorage', settings);
67-
});
59+
autorun(
60+
() => {
61+
const settings: PersistentSettings = {
62+
sidebarVisible: this.sidebarVisible,
63+
unit: this.unit,
64+
balanceMode: this.balanceMode,
65+
};
66+
this._store.storage.set('settings', settings);
67+
this._store.log.info('saved settings to localStorage', settings);
68+
},
69+
{ name: 'settingsAutorun' },
70+
);
6871
}
6972

7073
/**

app/src/store/stores/uiStore.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export default class UiStore {
8585
}
8686

8787
/** handle errors by showing a notification and/or the auth screen */
88+
@action.bound
8889
handleError(error: Error, title?: string) {
8990
if (error instanceof AuthenticationError) {
9091
// this will automatically redirect to the auth page

0 commit comments

Comments
 (0)