В mobx у вас есть два варианта, когда вы хотите наблюдать изменения в чем-то, что можно наблюдать.reaction
и observe
.Reaction
позволяет указать, когда вы хотите, чтобы какая-то функция вызывалась, когда изменяется конкретный аспект наблюдаемого.Это могут быть изменения длины массива, ключей, свойств, что угодно.observe
вызовет некоторую функцию каждый раз, когда наблюдаемое изменилось.
Я подозреваю, что причина, по которой ваша реакция не была вызвана, связана с первой функцией.() => criteria.filter
.Это не будет срабатывать при добавлении / удалении ключа или изменении значения.Вместо этого он будет срабатывать, когда filter
действительно изменится.А поскольку filter
действительно является ссылкой на Карту, она никогда не изменится, даже если сама Карта изменится.
Вот несколько примеров, иллюстрирующих мою точку зрения:
Если вы хотитевызвать реакцию, когда ключ был добавлен или удален, вы можете захотеть, чтобы ваша функция была:
() => criteria.filter.keys()
Результат этой функции будет другим, когда ключ был добавлен илиудален.Точно так же, если вы хотите вызвать реакцию, когда значение было изменено, должно сработать что-то вроде этого:
() => criteria.filter.values()
Так что некоторая комбинация этих двух должна быть именно тем, что вам нужнослушать изменения ключей / значений.В качестве альтернативы вы можете использовать observe
, который будет срабатывать при каждом изменении и требовать от вас проверки того, что изменилось, чтобы убедиться, что ваши конкретные условия были выполнены, чтобы гарантировать вызов функции (т. Е. Изменение ключа / значения)
ОБНОВЛЕНИЕ: Вот пример, который иллюстрирует проблему
@observable map = new Map();
Позволяет сказать, что значение карты в памяти равно 5. Поэтому, когда вы проверяете map === map
, это эквивалентно 5 === 5
и будет оцениваться как true.
Теперь, глядя на первый фрагмент кода, который вы разместили:
reaction(() => map, data => console.log(map.toJSON()));
Каждый раз, когда выдобавить / удалить ключ или изменить значение, эта первая функция будет запущена.И результат будет 5, так как это то, что мы сказали, значение в памяти для этого примера.Он скажет: старое значение 5, а новое значение 5, поэтому никаких изменений нет.Поэтому реакция не запустит вторую функцию.
Теперь второй фрагмент:
reaction(() => map.toJSON(), data => console.log(data));
Сначала результат функции будет: {}
потому что карта пуста.Теперь давайте добавим ключ:
map.set(1, 'some value');
Теперь результат первой функции будет:
{"1": "some value"}
Понятно, что этозначение отличается от {}
, поэтому что-то изменилось, и называется вторая функция реакции.