Почему обработчик событий React не вызывается в dispatchEvent?

рассмотрим следующий элемент ввода в компоненте React:

<input onChange={() => console.log('onChange')} ... />

при тестировании компонента React я эмулирую пользователя, изменяя входное значение:

input.value = newValue;
TestUtils.Simulate.change(input);

это приводит к 'onChange' регистрироваться, как и ожидалось.

однако, когда 'change' событие отправляется напрямую (я использую jsdom):

input.value = newValue;
input.dispatchEvent(new Event('change'));

на onChange обработчик не вызывается.

почему?

моя мотивация, чтобы использовать dispatchEvent а чем TestUtils.Simulate потому что TestUtils.Simulate не поддерживает пузырение событий, и поведение моего компонента зависит от этого. Интересно, есть ли способ проверить без TestUtils.Simulate?

2 ответов


React использует свою собственную систему событий с SyntheticEvents (предотвращает incompatabilities браузера и дает реагируют больше контроля событий).

используя TestUtils правильно создает такое событие, которое вызовет ваше onChange слушатель.

на dispatchEvent функция, с другой стороны, создаст "родное" событие браузера. Но обработчик событий, который у вас есть, управляется react и поэтому реагирует только (badumts) на reacts SyntheticEvents.

вы можете прочитать о событиях react здесь: https://facebook.github.io/react/docs/events.html


один способ сделать это без ReactTestUtils.Simulate:

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://unpkg.com/react-trigger-change/dist/react-trigger-change.js';
document.head.appendChild(script);
input.value = value;
reactTriggerChange(input);

посмотреть источник react-trigger-change просто подбирать то, что нужно. Пример фрагмента:

if (nodeName === 'select' ||
    (nodeName === 'input' && type === 'file')) {
    // IE9-IE11, non-IE
    // Dispatch change.
    event = document.createEvent('HTMLEvents');
    event.initEvent('change', true, false);
    node.dispatchEvent(event);
  }