0

I'm attempting to trigger a mobx reaction when an item is added to or removed from an observable array.

Currently it's only triggered when removing an item

type QueryParam = {
    name: string
    value: string
}

export default class SelectStore {
    rootStore: RootStore;
    constructor(rootStore: RootStore) {
        this.rootStore = rootStore;
    }

    @observable testRunFilters: QueryParam[] = [];

    @action updateTestRunFilter = (queryParam: QueryParam) => {
        const existingParam = this.testRunFilters.find(q => q.name === queryParam.name && q.value === queryParam.value);
        if (!existingParam) {
            this.testRunFilters.push(queryParam);
            //console.log('In updateTestRunFilter' + this.testRunFilters);
        }
    }

    @action removeTestRunFilter = (queryParamName: string) => {
        const existingParam = this.testRunFilters.find(q => q.name === queryParamName);
        if (existingParam) {
            this.testRunFilters = this.testRunFilters.filter(q => q.name !== queryParamName);
            //console.log('In removeTestRunFilter' + this.testRunFilters);
        }
    }

    myReaction = reaction(
        () => this.testRunFilters,
        (testRunFilters) => {
            console.log('Hello!' + testRunFilters);
        }
    );
}

The console.log in updateTestRunFilter is being triggered so I'm not sure what is wrong here?

I can't get it to work with a Map either, e.g. @observable testRunFiltersMap = new Map();

Konzy262
  • 2,747
  • 6
  • 42
  • 71

1 Answers1

2

Your reaction is wrong. The way it is now, it will only be triggered when you completely change the array ( new reference ). In order to trigger the reaction, you need to watch for the length property of the array. However, now the parameter that will be passed to the side effect will be just the array length.

   myReaction = reaction(
        () => this.testRunFilters.length,
        (thisIsLengthNow) => {
            console.log('Hello!' + testRunFilters);
        }
    );

But you can always return more stuff from the reaction or just access the array with this.testRunFilters in side effect.

Ivan V.
  • 7,593
  • 2
  • 36
  • 53