wolverine239
wolverine239

Reputation: 265

Mobx Observable not triggering changes

I've been working to implement MobX into one of my classes, and I believe I'm close to have it working but I'd really appreciate if someone can point out where I'm going wrong here.

Essentially when the refreshJobs() function runs, I'd like the render() function to execute again. From my understanding, if I updated the observable object jobs, the computed functions (renderSubmittedJobs(), renderInProgressJobs()) would run again producing new values, then the render function would run again since those values have been updated.

However, what happens with this code is that it updates this.jobs (wrapped in an action), but neither of the computed functions execute - and I believe that is why render isn't ran again either.

Does anyone know what might be causing this issue? I really appreciate any direction with this.

@observer
export default class Jobs extends React.Component<ScreenProps<>> {

    @observable jobs = {};

    @computed get renderInProgressJobs() {
        inProgressJobs = [];
        for (key in this.jobs) {
            if (jobs[key].status === "in progress") {
                inProgressJobs.push(this.jobs[key]);
            }
        }
        return this.renderJobComponents(inProgressJobs);
    }

    @computed get renderSubmittedJobs() {
        submittedJobs = [];
        for (key in this.jobs) {
            console.log(key)
            if (this.jobs[key].status !== "in progress") {
                submittedJobs.push(this.jobs[key]);
            }
        }
        return this.renderJobComponents(submittedJobs);
    }

    renderJobComponents(jobList: Array) {
      return jobList.map((jobInfo, key) => {
        return (
          ...
        );
      });
    }

    @observer
    async refreshJobs() {
        jobs = await grabClientJobs(refresh=true);
        await runInAction("Updating Jobs", async () => {
            this.jobs = jobs;
        });
    }

    @observer
    async componentWillMount() {
        jobs = await grabClientJobs();
        runInAction("Updating Jobs", async () => {
            this.jobs = jobs;
        });
    }

    @observer
    render(): React.Node {

        console.log('in jobs now');
        return <BaseContainer title="Jobs" navigation={this.props.navigation} scrollable refresh={this.refreshJobs}>
            <Tabs renderTabBar={()=> <ScrollableTab />} tabBarUnderlineStyle={style.secondaryBackground}>
             <Tab heading="In Progress" textStyle={style.tabTextStyle} activeTextStyle={style.activeTabTextStyle}>
               { this.renderInProgressJobs }
               <Button full style={[style.secondaryBackground, style.newJob]}>
                 <Text>CREATE NEW JOB</Text>
               </Button>
             </Tab>
             <Tab heading="Submitted" textStyle={style.tabTextStyle} activeTextStyle={style.activeTabTextStyle}>
               { this.renderSubmittedJobs }
             </Tab>
           </Tabs>
        </BaseContainer>;
    }
}

Upvotes: 3

Views: 3609

Answers (1)

XPX-Gloom
XPX-Gloom

Reputation: 601

few mistakes here:

  1. you can't re-assign another value to the observable variable, it'll destroy the observable. You need to mutate the observable. For example, you can directly assign values to existing properties or use extendObservable for assigning new properties to observable object.

  2. If you use MobX < 4, adding new properties the observable object will not trigger changes because the properties are set when the observable object was created. extendObservable may work but it's also limited. Use observable Map instead.

  3. @observer should be used for component class (or SFC), not member functions inside of the class

Upvotes: 3

Related Questions