Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Computed properties evaluated before property assignment #1608

Closed
johnrichter opened this issue Jun 27, 2018 · 2 comments
Closed

Computed properties evaluated before property assignment #1608

johnrichter opened this issue Jun 27, 2018 · 2 comments

Comments

@johnrichter
Copy link

johnrichter commented Jun 27, 2018

Summary

I'm having an issue which I'm struggling to troubleshoot. It seems as though computed values are preemptively evaluated before initial values to class member variables are assigned. At times it happens with all computed values and others it seems to only happen with Map computed values.

Here are some screen captures that I made to help demonstrate the problem. I'm triggering the exceptions by clicking the Props > store drop down for the Provider component.

computednumberfromobjectpropertyref

computednumberfromcalculation

computedmap

computedarray

computedallrendered

I would expect that each of these computed values to not throw exceptions/instantiate new values when the store is inspected by dev tools.

Example Code

testStore.ts

import * as mobx from 'mobx';
import { observable, computed, runInAction } from 'mobx';

export class TestStore {
    @observable private _bases!: mobx.IObservableArray<number>;

    constructor() {
        runInAction(() => {
            this._bases = observable.array([0, 1, 2, 3, 4, 5]);
        });
    }

    public get bases(): mobx.IObservableArray<number> {
        return this._bases;
    }

    @computed public get numBases(): number {
        return this._bases.length;
    }

    @computed public get sumOfBases(): number {
        return this._bases.reduce((p: number, c: number) => p + c);
    }

    @computed public get squares(): Map<number, number> {
        let sqmp: Map<number, number> = new Map<number, number>([]);
        for (const b of this._bases) {
            sqmp.set(b, b * b);
        }
        return sqmp;
    }

    // @computed public get squares(): Array<number> {
    //     return this._bases.map((b: number) => b * b);
    // }
}

testApp.tsx

import * as React from 'react';
import { observer, inject } from 'mobx-react';
import { TestStore } from './testStore';

export interface ITestAppP {
    store?: TestStore;
}

export interface ITestAppS {

}

@inject('store')
@observer
export class TestApp extends React.Component<ITestAppP, ITestAppS> {
    constructor(props: ITestAppP) {
        super(props);
        this.state = {};
    }

    public render(): React.ReactNode {
        return (
            <div>
                <p>Bases: {JSON.stringify(this.props.store!.bases)}</p>
                <p>Num of Bases: {this.props.store!.numBases}</p>
                <p>Sum of Bases: {this.props.store!.sumOfBases}</p>
                <p>Squares: {JSON.stringify(Array.from(this.props.store!.squares.entries()))}</p>
            </div>
        );
    }
}

index.tsx

import * as mobx from 'mobx';
mobx.configure({
    enforceActions: 'strict',
    isolateGlobalState: true
});

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as MobxReact from 'mobx-react';
import { TestApp } from './testApp';
import { TestStore } from './testStore';

const testStore: TestStore = new TestStore();

ReactDOM.render(
    (
        <MobxReact.Provider store={testStore}>
            <TestApp />
        </MobxReact.Provider>
    ),
    document.getElementById('root')
);

I've searched the depth of Google, Stack Overflow, and MobX repositories to find answers, but have not found any closely related, documented (solved or not) issues or questions to the one I've outlined above.

Versions

Built from an ejected Create React App w/ react-scripts-ts.

{
    "@types/react": "^16.3.17",
    "@types/react-dom": "^16.0.5",
    "react": "^16.4.0",
    "react-dev-utils": "^5.0.1",
    "react-dom": "^16.4.0",
    "mobx": "^4.3.1",
    "mobx-react": "^5.2.0",
    "mobx-react-devtools": "^5.0.1",
    "mobx-utils": "^5.0.0",
    "typescript": "^2.9.1",
    "webpack": "3.11.0",
    "webpack-dev-server": "2.11.1",
    "webpack-manifest-plugin": "1.3.2",
}
@urugator
Copy link
Collaborator

urugator commented Jun 27, 2018

Probably react-devtools issue, check
facebook/react-devtools#976
facebook/react-devtools#893
facebook/react-devtools#390

@johnrichter
Copy link
Author

Looks like that is a highly likely candidate. I'll start tracking the PR for that bug (facebook/react-devtools#569) and close this issue for now. If I'm still having issues after that gets merged and released I'll reopen 👍

Thanks for the second look! I can't believe I didn't think to look at the react-devtools repo 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants