Quando eu estava tentando este exemplo em https://facebook.github.io/react/blog/2013/11/05/thinking-in-react.html , quaisquer caracteres chineses inseridos pelo método de entrada pinyin chinês disparariam muitos renderizadores, como :
Na verdade, eu esperaria que eles não disparassem antes de eu confirmar o caractere chinês.
Então tentei outro tipo de método de entrada - método de entrada wubi, eu consegui isso:
É estranho também. Então, fiz um teste no jQuery :
Somente depois de pressionar a barra de espaço para confirmar o caractere, o evento keyup
seria disparado.
Eu sei que pode ser diferente entre a implementação de jQuery keyup
e a reação onChange
, mas eu esperaria a maneira como a jQuery keyup
lida com caracteres chineses em vez de onChange
de reação
cc @salier :) - O que devemos fazer aqui?
Acho que não devemos disparar onChange
até que a string IME seja confirmada.
Uma maneira de lidar com isso em ChangeEventPlugin
seria ignorar todos os eventos input
entre compositionstart
e compositionend
, em seguida, usar o evento input
imediatamente seguindo compositionend
.
Fiz alguns testes rápidos no OSX Chrome e Firefox com Simplified Pinyin e 2-Set Korean, e a ordem do evento e os dados parecem corretos o suficiente. (Prevejo que teremos problemas com o IE coreano, mas podemos ter sorte.)
Acho que podemos continuar a ver problemas com métodos de entrada alternativos, como a extensão do Google Input Tools, mas pode haver soluções alternativas para isso.
Isso também influencia como os caracteres dialéticos são digitados para as línguas latinas. Até mesmo pressionar e
e usar a variante está falhando aqui.
Desculpe, isso parece não estar relacionado. Me desculpe.
Existe alguma atualização? Sofrendo com esse problema também.
Nenhum atualmente - esta não é uma alta prioridade para nós agora. Ficaria feliz em ver uma solicitação pull, se alguém se empenhar em consertar isso.
@salier Parece que o IE não dispara o evento input
após compositionend
. Eu testei no IE11 e Edge no Windows 10. Ele dispara corretamente no Chrome e Firefox.
no exemplo 9, o evento Change dispara muitas vezes ao inserir caracteres chineses novamente
Olá, pessoal do Facebook, na verdade este problema causa um problema SÉRIO : não podemos atualizar a entrada de forma assíncrona com a entrada em chinês.
Por exemplo, não podemos usar fontes de dados reativas de meteoros ou armazenamentos como redux, porque todos os comentários são atualizados de forma assíncrona.
Aqui está um exemplo mais simples para mostrar esse problema, use setTimeout para fazer a atualização assíncrona:
https://jsfiddle.net/liyatang/bq6oss6z/1/
Eu realmente espero que você possa corrigir isso rapidamente, para que não percamos esforços para contornar isso aqui e ali e novamente.
Obrigado.
Aqui está minha solução alternativa . Se alguém enfrentar o mesmo problema, você pode dar uma olhada
Fiz um exemplo simples para demonstrar como usar compositionstart
e compositionend
eventos para evitar a entrada de IME chinês em um problema de evento onchange
.
Aqui está o link: https://jsfiddle.net/eyesofkids/dcxvas28/8/
@eyesofkids bom trabalho, isso poderia ser feito como a implementação padrão de onChange
para entrada, textarea ...
bom trabalho !
Eu estava tendo o mesmo problema e a solução alternativa do @eyesofkids funciona perfeitamente (obrigado!).
Depois de implementar a solução alternativa, eu estava mergulhando no código-fonte do React para pelo menos tentar adicionar um teste com falha para isso - esperando adicionar mais tarde o comportamento esperado à biblioteca - embora pareça um pouco complicado para alguém não familiarizado com os componentes internos.
Inicialmente, esperava que um teste semelhante ao que já está disponível para ChangeEventPlugin
deveria funcionar, ou seja, simular um compositionStart
/ compositionUpdate
nativo e não verificar nenhum retorno de chamada onChange
disparamos; também verificar onChange
só seria disparado quando compositionEnd
fosse simulado. No entanto, isso não parece funcionar.
Portanto, eu estava pensando que talvez verificar ChangeEventPlugin.extractEvents()
seria uma abordagem viável, semelhante ao que foi feito nos testes para SelectEventPlugin
. Aqui, por alguma razão, eu sempre recebo undefined
ao extrair os eventos.
Para referência, este é o código de teste que tentei em _ChangeEventPlugin-test.js_:
var EventConstants = require('EventConstants');
var ReactDOMComponentTree = require('ReactDOMComponentTree');
var topLevelTypes = EventConstants.topLevelTypes;
function extract(node, topLevelEvent) {
return ChangeEventPlugin.extractEvents(
topLevelEvent,
ReactDOMComponentTree.getInstanceFromNode(node),
{target: node},
node
);
}
function cb(e) {
expect(e.type).toBe('change');
}
var input = ReactTestUtils.renderIntoDocument(
<input onChange={cb} value='foo' />
);
ReactTestUtils.SimulateNative.compositionStart(input);
var change = extract(input, topLevelTypes.topChange);
expect(change).toBe(null);
Receio não saber exatamente como se deve depurar esses testes - caso contrário, teria uma imagem mais clara do que está acontecendo. Qualquer orientação sobre como proceder ou quaisquer outras dicas seriam muito apreciadas.
A solução repentinamente quebrou no Chrome 53+ e parece que não é mais válido porque eles mudaram a ordem de compositionend
é disparado : anteriormente isso acontecia antes de textInput
, agora depois de textInput
. Como consequência disso, change
não será disparado se for abortado durante a composição 😕.
https://github.com/suhaotian/react-input talvez ajude alguém
Existe uma solução complicada para o Chrome v53. Para chamar o handlechange após compositionend
ser disparado.
handleComposition = (event) => {
if(event.type === 'compositionend'){
onComposition = false
//fire change method to update for Chrome v53
this.handleChange(event)
} else{
onComposition = true
}
}
verifique a demonstração aqui: https://jsfiddle.net/eyesofkids/dcxvas28/11/
@chenxsan você descobriu a solução?
você pode detectar o compositionStart e deixar uma variável igual a true.
Em seguida, para usar a variável, que você definiu, em onChange para ver se ela deve disparar a consulta
Eu enviei um novo problema para componentes controlados em # 8683
A solução temporária para componentes não controlados e controlados (entrada, área de texto) é carregada para o evento de composição de reação .
Vamos fazer https://github.com/facebook/react/pull/8438 acontecer.
@yesmeck muito feliz em ver esta notícia.
Eu vi o teste focar apenas no Webkit, ele deve ser separado em Chrome e Safari porque o Chrome muda sua ordem de compositionend
acionada por evento após 53+.
@eyesofkids Adicionado um novo caso de teste para Chrome com menos de 53 anos.
Só para colocar lenha na fogueira, estou tentando contornar esse problema e descobri que a versão atual do iOS safari não aciona o evento compositionend
ao usar o IME Hiragana japonês, acho que isso é intencional, pois o menu de composição parece nunca estar fechado.
No exemplo de solução alternativa @eyesofkids, o inputValue nunca é atualizado, embora para mim https://github.com/zhaoyao91/react-optimistic-input corrija o problema com o IME japonês.
Para quem procura uma solução para isso, aqui está um componente pronto para uso. https://github.com/aprilandjan/react-starter/blob/test/search-input/src/components/SearchInput.js Basta usá-lo em vez do elemento de entrada de texto normal e está tudo ok.
@ zhaoyao91 sua solução alternativa simplesmente funciona! muito obrigado.
ei pessoal alguma novidade nessa edição?
Não tem sido uma prioridade alta porque os disparos de onChange com muita frequência raramente causam problemas. Onde isso está causando problemas em seu aplicativo?
@sophiebits desculpe clicou acidentalmente no 'X'. Isso pode degradar o desempenho se houver operações de filtragem ou retornos de chamada do servidor usados nos manipuladores de eventos de mudança. A abordagem mostrada em https://github.com/facebook/react/issues/3926#issuecomment -316049951 é uma boa solução alternativa para entradas não controladas ou nativas, mas não mapeia bem para entradas controladas pelo React. Parece que alguns neste tópico tentaram desenvolver um PR, mas acharam os aspectos internos um pouco complexos - mas talvez um engenheiro da sua equipe pudesse fazer o trabalho mais rápido? https://github.com/facebook/react/issues/8683 é uma descrição muito melhor do problema real da IMO.
Alguém pode me ajudar a entender: o problema está estritamente em onChange
chamadas extras no meio ? Ou você obtém um valor incorreto no final?
O teste da tentativa de correção em https://github.com/facebook/react/pull/8438 passa se eu remover a afirmação sobre o número de vezes que onChange
é chamado. Portanto, suponho que esse problema seja apenas sobre as onChange
chamadas extras.
não há chamadas onChange extras, é apenas obter o valor incorreto no final, parece mais um problema onComposition.
@crochefluid Você pode criar um teste de falha para isso? Semelhante ao que # 8438 tentou fazer. Nesse teste, não houve valor incorreto.
@gaearon , vou tentar. Você tentou esse teste no safari (mac / IOS)?
É um teste de Nó, mas codifica sequências capturadas de diferentes navegadores e dispositivos. Por favor, veja sua fonte. Você precisaria adicionar sequências que estão falhando.
Portanto, suponho que esse problema seja apenas sobre as chamadas onChange extras.
Exatamente.
Ainda estou tendo esse problema. Parece que este problema está aberto há 3 anos. O React oferece suporte a entrada chinesa em componentes controlados no momento?
Também vendo isso em japonês com certos caracteres ...
Aqui está uma caixa de proteção de código que reproduz meu problema. Parece que está relacionado a formulários. Usar entradas diretamente está bom.
Eu adicionei alguns casos:
Usar o estado de reação e entradas simples é bom
Usar o estado de reação, formulários simples e entradas simples é bom
Estamos usando um componente de formulário baseado em contexto que não está funcionando. Pode ser um problema relacionado ao contexto.
Problema resolvido: comecei a trabalhar no codepen. Por alguma razão, passar 'input' como um componente funcionou, ao passar (props) => nao fiz.
Alguém tem ideia de qual é a diferença?
Na verdade, eu também tentei:
Trabalho
<Field {...otherProps} component="input" />
Não funciona
<Field {...otherProps} component={(props) => <input {...props} />} />
Funciona estranhamente
const WrappedInput = (props) => <input {...props} />
...
<Field {...otherProps} component={WrappedInput} />
É claro que há alguma mágica acontecendo aqui que eu não entendo. 😕
Alguma atualização?
Parece causar resultado incorreto quando o IME está habilitado
Eu experimentei o mesmo problema que @otakustay
Parece impossível oferecer suporte a entrada controlada com entrada IME. Eu tracei a sequência de eventos para o seguinte.
w
input
por meio do atributo value
.w
no elemento de entradaw
separada armazenada no buffer IMEa
a
combina com a string o buffer IME para produzir wwa
.Percebi que o bug só ocorre se a entrada for renderizada novamente> 15ms após o evento compositionUpdate após a próxima repintura.
No momento, minha única solução é deixar de usar as entradas controladas.
Edit : Aqui está uma reprodução simples: https://jsfiddle.net/kbhg3xna/
Edit2 : Aqui está minha solução alternativa para hacky: https://jsfiddle.net/m792qtys/ cc: @otakustay
Alguma atualização sobre isso?
atualizar ??
alguma atualização disso?
Atordoado, fui confrontado com esta questão
Interessante, parece que o problema não é apenas sobre o onChange multi-vezes. Se não setState entre onCompositionStart
e onCompositionEnd
, a reação irá "controlar" o valor como está. Esta ação interromperá a composição. Isso significa que não obteremos o evento onCompositionEnd
...... (Se estiver errado, mencione-me plz.) Mas só podemos mudar o estado imediatamente (Caso contrário, teremos que enfrentar o problema @ knubie menciona). Uma reprodução aqui (parece um componente "meio controlado"): https://gist.github.com/cpdyj/6567437d96c315e9162778c8efdfb6e8
Mas estou tão surpreso que o problema não tenha solução durante cinco anos 😢
@hellendag Acho que não devemos disparar onChange até que a string IME seja confirmada.
Não acho que seja uma solução válida, pois um componente pode querer saber a string IME "não confirmada" para, por exemplo, opções de filtragem em uma lista conforme o usuário digita.
Não tenho certeza se a abordagem que uso neste outro tópico pode ajudar aqueles que estão enfrentando esse problema, mas aqui está um link para o caso: https://github.com/facebook/react/issues/13104#issuecomment -691393940
alguma atualização?
Comentários muito úteis
Olá, pessoal do Facebook, na verdade este problema causa um problema SÉRIO : não podemos atualizar a entrada de forma assíncrona com a entrada em chinês.
Por exemplo, não podemos usar fontes de dados reativas de meteoros ou armazenamentos como redux, porque todos os comentários são atualizados de forma assíncrona.
Aqui está um exemplo mais simples para mostrar esse problema, use setTimeout para fazer a atualização assíncrona:
https://jsfiddle.net/liyatang/bq6oss6z/1/
Eu realmente espero que você possa corrigir isso rapidamente, para que não percamos esforços para contornar isso aqui e ali e novamente.
Obrigado.
Aqui está minha solução alternativa . Se alguém enfrentar o mesmo problema, você pode dar uma olhada