Мы используем пакет Backbone + ReactJS для создания клиентского приложения. Сильно полагаясь на пресловутые valueLink
мы распространяем значения напрямую в модель через собственную оболочку, поддерживающую интерфейс ReactJS для двусторонней привязки.
Теперь мы столкнулись с проблемой:
У нас есть jquery.mask.js
плагин, который программно форматирует входное значение, поэтому он не запускает события React. Все это приводит к тому, что модель получает неформатированные значения от пользовательского ввода и пропускает отформатированные от плагина.
Кажется, что у React есть множество стратегий обработки событий в зависимости от браузера. Есть ли какой-нибудь общий способ инициировать событие изменения для определенного элемента DOM, чтобы React его услышал?
Ответы:
Для React 16 и React> = 15,6
Сеттер
.value=
не работает так, как мы хотели, потому что библиотека React переопределяет установщик входных значений, но мы можем вызвать функцию непосредственноinput
в контексте as.Для TEXTAREA элемента следует использовать
prototype
вHTMLTextAreaElement
классе.Новый пример кода .
Все кредиты этому участнику и его решению
Устаревший ответ только для React <= 15.5
С помощью
react-dom ^15.6.0
вы можете использоватьsimulated
флаг на объекте события, чтобы событие прошло черезЯ сделал код с примером
Чтобы понять, зачем нужен новый флаг, я нашел этот комментарий очень полезным:
источник
По крайней мере,
onChange
при вводе текста кажется, что он прослушивает события ввода:источник
Event
не поддерживает IE https://developer.mozilla.org/en-US/docs/Web/API/Event/Eventvar event = document.createEvent('CustomEvent'); event.initCustomEvent('input', true, false, { });
, но у меня нет виртуальной машины IE9 под рукой.var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); document.getElementById('description').value = 'I changed description'; document.getElementById('description').dispatchEvent(evt);
Я знаю, что этот ответ приходит немного поздно, но недавно я столкнулся с аналогичной проблемой. Я хотел вызвать событие для вложенного компонента. У меня был список с виджетами типа радио и флажка (это были div, которые вели себя как флажки и / или переключатели), а в другом месте приложения, если кто-то закрыл панель инструментов, мне нужно было снять флажок.
Я нашел довольно простое решение, не уверен, что это лучшая практика, но оно работает.
Это вызвало событие щелчка на domNode, и мой обработчик, подключенный через response, действительно был вызван, поэтому он ведет себя так, как я ожидал, если кто-то щелкнет элемент. Я не тестировал onChange, но он должен работать, и не уверен, насколько это будет справедливо в действительно старых версиях IE, но я считаю, что MouseEvent поддерживается как минимум в IE9 и выше.
В конце концов я отошел от этого для моего конкретного варианта использования, потому что мой компонент был очень маленьким (реагирует только часть моего приложения, поскольку я все еще изучаю его), и я мог добиться того же другим способом, не получая ссылок на узлы dom.
ОБНОВИТЬ:
Как отмечали другие в комментариях, лучше использовать
this.refs.refname
для получения ссылки на узел dom. В этом случае refname - это ссылка, которую вы прикрепили к своему компоненту через<MyComponent ref='refname' />
.источник
React.findDOMNode
функцию. goo.gl/RqccrAref
к своему элементу, затем используйтеthis.ref.refName.dispatchEvent
Вы можете моделировать события с помощью ReactTestUtils, но он предназначен для модульного тестирования.
Я бы рекомендовал не использовать valueLink в этом случае, а просто прослушивать события изменения, запускаемые плагином, и обновлять состояние ввода в ответ. Двусторонняя привязка используется больше как демонстрация, чем что-либо еще; они включены в надстройки только для того, чтобы подчеркнуть тот факт, что чистая двусторонняя привязка не подходит для большинства приложений и что вам обычно требуется больше логики приложения для описания взаимодействий в вашем приложении.
источник
ReactTestUtils.Simulate.change(ReactDOM.findDOMNode(this.fieldRef))
Продолжая ответ Грина / Дэна Абрамова, это работает с несколькими типами ввода. Протестировано в React> = 15.5
источник
Запуск событий изменения для произвольных элементов создает зависимости между компонентами, о которых трудно рассуждать. Лучше придерживаться одностороннего потока данных React.
Нет простого фрагмента для запуска события изменения React. Логика реализована в ChangeEventPlugin.js, и есть разные ветки кода для разных типов ввода и браузеров. Более того, детали реализации различаются в зависимости от версии React.
Я создал response-trigger-change, который делает это, но он предназначен для использования для тестирования, а не как производственная зависимость:
CodePen
источник
ну, поскольку мы используем функции для обработки события onchange, мы можем сделать это следующим образом:
источник
Я нашел это в проблемах React Github: работает как шарм (v15.6.2)
Вот как я реализовал ввод текста:
источник
Ибо
HTMLSelectElement
, т.е.<select>
источник
Тип события
input
у меня не работал,<select>
но изменил его наchange
работаетисточник
Если вы используете Backbone и React, я бы порекомендовал одно из следующих:
Оба они помогают интегрировать модели и коллекции Backbone с представлениями React. Вы можете использовать события Backbone точно так же, как и представления Backbone. Я попробовал оба и не заметил особой разницы, за исключением того, что один является миксином, а другой изменяется
React.createClass
наReact.createBackboneClass
.источник