Usamos o pacote Backbone + ReactJS para construir um aplicativo do lado do cliente. Contando fortemente com o notório valueLink
, propagamos valores diretamente para o modelo por meio do próprio invólucro que suporta a interface ReactJS para vinculação bidirecional.
Agora enfrentamos o problema:
Temos um jquery.mask.js
plugin que formata o valor de entrada programaticamente, portanto, não dispara eventos React. Tudo isso leva a uma situação em que o modelo recebe valores não formatados da entrada do usuário e perde os formatados do plugin.
Parece que o React tem muitas estratégias de manipulação de eventos, dependendo do navegador. Existe alguma maneira comum de acionar o evento de alteração para um elemento DOM específico para que o React o ouça?
Respostas:
Para React 16 e React> = 15,6
Setter
.value=
não está funcionando como queríamos porque a biblioteca React substitui o setter de valor de entrada, mas podemos chamar a função diretamente noinput
contexto as.Para elemento textarea você deve usar
prototype
deHTMLTextAreaElement
classe.Novo exemplo de codepen .
Todos os créditos para este contribuidor e sua solução
Resposta desatualizada apenas para React <= 15,5
Com
react-dom ^15.6.0
você pode usar osimulated
sinalizador no objeto de evento para o evento passarEu fiz um codepen com um exemplo
Para entender por que um novo sinalizador é necessário, achei este comentário muito útil:
fonte
Pelo menos em entradas de texto, parece que
onChange
está ouvindo eventos de entrada:fonte
Event
não é compatível com o IE https://developer.mozilla.org/en-US/docs/Web/API/Event/Eventvar event = document.createEvent('CustomEvent'); event.initCustomEvent('input', true, false, { });
, mas não tenho uma VM do IE9 à mão.var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); document.getElementById('description').value = 'I changed description'; document.getElementById('description').dispatchEvent(evt);
Sei que essa resposta chega um pouco tarde, mas recentemente enfrentei um problema semelhante. Eu queria acionar um evento em um componente aninhado. Eu tinha uma lista com widgets do tipo rádio e caixa de seleção (eram divs que se comportavam como caixas de seleção e / ou botões de rádio) e em algum outro lugar do aplicativo, se alguém fechasse uma caixa de ferramentas, eu precisava desmarcar uma.
Eu encontrei uma solução muito simples, não tenho certeza se essa é a melhor prática, mas funciona.
Isso acionou o evento click no domNode e meu manipulador anexado via react foi de fato chamado para se comportar como eu esperaria se alguém clicasse no elemento. Não testei o onChange, mas deve funcionar, e não tenho certeza de como isso funcionará em versões realmente antigas do IE, mas acredito que o MouseEvent é suportado pelo menos no IE9 e superior.
Eventualmente, afastei-me disso para meu caso de uso específico porque meu componente era muito pequeno (apenas uma parte de meu aplicativo costumava reagir, pois ainda estou aprendendo) e eu poderia fazer a mesma coisa de outra maneira sem obter referências a nós dom.
ATUALIZAR:
Como outros afirmaram nos comentários, é melhor usar
this.refs.refname
para obter uma referência a um nó dom. Neste caso, refname é o ref que você anexou ao seu componente por meio<MyComponent ref='refname' />
.fonte
React.findDOMNode
função. goo.gl/RqccrAref
ao seu elemento e usethis.ref.refName.dispatchEvent
Você pode simular eventos usando ReactTestUtils, mas isso é projetado para teste de unidade.
Eu recomendo não usar valueLink para este caso e simplesmente ouvir os eventos de mudança disparados pelo plug-in e atualizar o estado da entrada em resposta. A vinculação bidirecional é mais uma demonstração do que qualquer outra coisa; eles são incluídos em complementos apenas para enfatizar o fato de que a vinculação bidirecional pura não é apropriada para a maioria dos aplicativos e que você geralmente precisa de mais lógica de aplicativo para descrever as interações em seu aplicativo.
fonte
ReactTestUtils.Simulate.change(ReactDOM.findDOMNode(this.fieldRef))
Expandindo a resposta de Grin / Dan Abramov, isso funciona em vários tipos de entrada. Testado em React> = 15,5
fonte
O disparo de eventos de mudança em elementos arbitrários cria dependências entre componentes que são difíceis de raciocinar. É melhor seguir o fluxo de dados unilateral do React.
Não existe um snippet simples para acionar o evento de mudança do React. A lógica é implementada em ChangeEventPlugin.js e existem diferentes ramificações de código para diferentes tipos de entrada e navegadores. Além disso, os detalhes de implementação variam entre as versões do React.
Eu construí o react-trigger-change que faz a coisa, mas se destina a ser usado para teste, não como uma dependência de produção:
CodePen
fonte
bem, uma vez que usamos funções para lidar com um evento onchange, podemos fazer assim:
fonte
Eu encontrei isso nos problemas do Github do React: Funciona como um encanto (v15.6.2)
Aqui está como eu implementei em uma entrada de texto:
fonte
Para
HTMLSelectElement
, ou seja<select>
fonte
Se você estiver usando o Backbone e o React, recomendo um dos seguintes,
Ambos ajudam a integrar modelos e coleções de Backbone com visualizações React. Você pode usar eventos do Backbone da mesma forma que faz com as visualizações do Backbone. Eu já experimentei ambos e não vi muita diferença, exceto um é um mixin e o outro muda
React.createClass
paraReact.createBackboneClass
.fonte