Cuando estaba probando este ejemplo de https://facebook.github.io/react/blog/2013/11/05/thinking-in-react.html , cualquier carácter chino ingresado por el método de entrada pinyin chino dispararía demasiadas representaciones como :
En realidad, esperaría que no disparen antes de confirmar el carácter chino.
Luego probé otro tipo de método de entrada: método de entrada wubi, obtuve esto:
También es extraño. Entonces hice una prueba en jQuery :
Solo después de presionar la barra espaciadora para confirmar el carácter, se activará el evento keyup
.
Sé que podría ser diferente entre la implementación de jQuery keyup
y reaccionar onChange
, pero esperaría la forma en que jQuery keyup
maneja los caracteres chinos en lugar de reaccionar onChange
.
cc @salier :) - ¿Qué debemos hacer aquí?
Creo que no deberíamos disparar onChange
hasta que la cadena IME esté confirmada.
Una forma de manejar esto en ChangeEventPlugin
sería ignorar todos los eventos input
entre compositionstart
y compositionend
, luego usar el evento input
inmediatamente siguiendo compositionend
.
Hice algunas pruebas rápidas en OSX Chrome y Firefox con Simplified Pinyin y 2-Set Korean, y el orden y los datos de los eventos parecen lo suficientemente correctos. (Predigo que tendremos problemas con IE Korean, pero es posible que tengamos suerte).
Creo que podemos seguir viendo problemas con métodos de entrada alternativos como la extensión Google Input Tools, pero puede haber soluciones para eso.
Esto también influye en cómo se escriben los caracteres dialécticos para los idiomas latinos. Incluso la pulsación larga e
y luego usar la variante están fallando aquí.
Lo siento, esto parece no estar relacionado. Mis disculpas.
¿Hay alguna actualización? Sufriendo de este problema también.
Ninguno actualmente, esto no es una prioridad para nosotros en este momento. Estaría feliz de ver una solicitud de extracción si alguien se sumerge en solucionar esto.
@salier Parece que IE no dispara el evento input
después de compositionend
. He probado en IE11 y Edge en Windows 10. Se dispara correctamente en Chrome y Firefox.
en ie 9, el evento Change se dispara demasiadas veces al ingresar caracteres chinos nuevamente
Hola, chicos de Facebook, de hecho, este problema causa un problema SERIO : no podemos actualizar la entrada de forma asincrónica con la entrada china.
Por ejemplo, no podemos usar fuentes de datos reactivas a meteoritos o tiendas como redux, porque todos los comentarios se actualizan de forma asincrónica.
Aquí hay un ejemplo más simple para mostrar este problema, usa setTimeout para hacer una actualización asíncrona:
https://jsfiddle.net/liyatang/bq6oss6z/1/
Realmente espero que pueda solucionar esto rápidamente, para que no desperdiciemos esfuerzos para solucionarlo aquí y allá y una y otra vez.
Gracias.
Aquí está mi solución . Si alguien se enfrenta al mismo problema, puede echar un vistazo
Hice un ejemplo simple para hacer una demostración de cómo usar los eventos compositionstart
y compositionend
para evitar ingresar IME chino en el problema del evento onchange
.
Aquí está el enlace: https://jsfiddle.net/eyesofkids/dcxvas28/8/
@eyesofkids buen trabajo, esto podría hacerse como la implementación predeterminada de onChange
para input, textarea ...
Buen trabajo !
Estaba teniendo el mismo problema y la solución de
Después de tener la solución en su lugar, me sumergí en el código fuente de React para al menos intentar agregar una prueba fallida para esto, con la esperanza de agregar más tarde el comportamiento esperado a la biblioteca, aunque parece un poco complicado para alguien que no está familiarizado con los componentes internos.
Inicialmente esperaba que una prueba similar a la que ya está disponible para ChangeEventPlugin
debería funcionar, es decir, simulando un compositionStart
/ compositionUpdate
nativo y verificando que no se haya devuelto la llamada onChange
despedido; además, la comprobación de onChange
solo se dispararía una vez que se simulara compositionEnd
. Sin embargo, esto no parece funcionar.
Por lo tanto, estaba pensando que tal vez verificar ChangeEventPlugin.extractEvents()
sería un enfoque factible, similar a lo que se hizo en las pruebas para SelectEventPlugin
. Aquí, por alguna razón, siempre obtengo undefined
cuando extraigo los eventos.
Como referencia, este es el código de prueba que probé dentro de _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);
Me temo que no sé exactamente cómo se supone que uno debe depurar estas pruebas; de lo contrario, tendría una idea más clara de lo que está sucediendo. Cualquier orientación sobre cómo proceder o cualquier otra sugerencia será muy apreciada.
La solución se rompió repentinamente en Chrome 53+ y parece que ya no es válida porque cambiaron el orden compositionend
se disparó : anteriormente sucedía antes de textInput
, ahora después de textInput
. Como consecuencia de esto, change
no se disparará si se cancela mientras está en composición 😕.
https://github.com/suhaotian/react-input tal vez ayudar a alguien
Existe una solución complicada para Chrome v53. Para llamar al handlechange después de que se dispare compositionend
.
handleComposition = (event) => {
if(event.type === 'compositionend'){
onComposition = false
//fire change method to update for Chrome v53
this.handleChange(event)
} else{
onComposition = true
}
}
consulte la demostración aquí: https://jsfiddle.net/eyesofkids/dcxvas28/11/
@chenxsan ¿encontraste la solución?
puede detectar la composición Comienzo y dejar una variable igual a verdadera.
Luego, use la variable, que estableció, en onChange para ver si debería disparar la consulta
Envié un nuevo problema para componentes controlados en # 8683
La solución temporal para componentes controlados y no controlados (entrada, área de texto) se carga en react-composicionevent .
Hagamos que https://github.com/facebook/react/pull/8438 suceda.
@yesmeck muy feliz de ver esta noticia.
Vi que la prueba solo se enfocaba en el Webkit, debería estar separado en Chrome y Safari porque Chrome cambia su orden activada por evento compositionend
después de 53+.
@eyesofkids Se agregó un nuevo caso de prueba para Chrome menores de 53 años.
Solo para agregar más leña al fuego, he estado tratando de solucionar este problema y descubrí que la versión actual de iOS safari no activa el evento compositionend
cuando se usa el IME japonés de Hiragana, creo que esto es intencional ya que el menú de composición nunca parece estar cerrado.
En la solución alternativa de ejemplo de @eyesofkids, inputValue nunca se actualiza, aunque para mí https://github.com/zhaoyao91/react-optimistic-input soluciona el problema con el IME japonés.
Para cualquiera que busque una solución para esto, aquí tiene un componente listo para usar. https://github.com/aprilandjan/react-starter/blob/test/search-input/src/components/SearchInput.js Simplemente úselo en lugar del elemento de entrada de texto normal y todo está bien.
@ zhaoyao91 ¡ tu solución simplemente funciona! muchas gracias.
hola chicos alguna noticia en este numero?
No ha sido una alta prioridad porque onChange disparar con demasiada frecuencia rara vez causa problemas. ¿Dónde está causando problemas en su aplicación?
@sophiebits lo siento, accidentalmente hizo clic en la 'X'. Esto puede degradar el rendimiento si se utilizan operaciones de filtrado o devoluciones de llamada del servidor en los controladores de eventos de cambio. El enfoque que se muestra en https://github.com/facebook/react/issues/3926#issuecomment -316049951 es una buena solución para las entradas nativas o no controladas, pero no se correlaciona bien con las entradas controladas por React. Parece que algunos en este hilo han intentado desarrollar un PR, pero encontraron los aspectos internos un poco complejos, pero ¿tal vez un ingeniero de su equipo podría hacerlo más rápido? https://github.com/facebook/react/issues/8683 es una descripción mucho mejor del problema real, en mi opinión.
¿Alguien puede ayudarme a entender: el problema está estrictamente en llamadas onChange
adicionales en el medio ? ¿O obtiene un valor incorrecto al final?
La prueba del intento de corrección en https://github.com/facebook/react/pull/8438 pasa si elimino la afirmación sobre la cantidad de veces que se llama onChange
. Así que supongo que este problema solo se trata de las llamadas adicionales onChange
.
no hay llamadas onChange adicionales, solo está obteniendo el valor incorrecto al final, parece más un problema de onComposition.
@crochefluid ¿Puede crear una prueba fallida para esto? Similar a lo que intentó hacer # 8438. En esa prueba, no hubo ningún valor incorrecto.
@gaearon , lo intentaré. ¿Probaste esa prueba en safari (mac / IOS)?
Es una prueba de nodo, pero codifica secuencias capturadas desde diferentes navegadores y dispositivos. Consulte su fuente. Debería agregar secuencias que fallan.
Así que supongo que este problema solo se trata de las llamadas onChange adicionales.
Exactamente.
Sigo teniendo este problema. Parece que este problema ha estado abierto durante 3 años, ¿React admite la entrada china en componentes controlados en este momento?
También viendo esto en japonés con ciertos caracteres ...
Aquí hay una caja de arena de código que reproduce mi problema. Parece que está relacionado con las formas. Usar entradas directamente está bien.
Agregué algunos casos:
Usar el estado de reacción y las entradas simples está bien
El uso de estado de reacción, formas simples y entradas simples está bien
Estamos usando un componente de formulario basado en contexto que no funciona. Puede ser un problema relacionado con el contexto.
Problema resuelto: lo hice funcionar en codepen. Por alguna razón, pasar 'input' como un componente funcionó, al pasar (props) => No.
¿Alguien tiene una idea de cuál es la diferencia?
De hecho, también probé:
Trabajos
<Field {...otherProps} component="input" />
No funciona
<Field {...otherProps} component={(props) => <input {...props} />} />
Funciona curiosamente
const WrappedInput = (props) => <input {...props} />
...
<Field {...otherProps} component={WrappedInput} />
Claramente, hay algo de magia aquí que no entiendo. 😕
¿Alguna actualización?
Parece causar un resultado incorrecto cuando IME está habilitado
Experimenté el mismo problema que @otakustay
Parece imposible admitir la entrada controlada con la entrada IME. He rastreado la secuencia de eventos hasta lo siguiente.
w
input
mediante el atributo value
.w
en el elemento de entradaw
separada almacenada en el búfer IMEa
a
combina con la cadena del búfer IME para producir wwa
.He notado que el error solo ocurre si la entrada se vuelve a renderizar > 15 ms después del evento de composiciónUpdate después del siguiente repintado.
En este momento, mi única solución es alejarme de las entradas controladas.
Editar : Aquí hay una reproducción simple: https://jsfiddle.net/kbhg3xna/
Edit2 : aquí está mi solución hacky: https://jsfiddle.net/m792qtys/ cc: @otakustay
¿Alguna actualización sobre esto?
actualizar ??
¿Algún avance en esto?
Aturdido, me enfrenté a esta pregunta
Interesante, parece que el problema no es solo sobre el cambio de varias veces. Si no establecemosState entre onCompositionStart
y onCompositionEnd
, la reacción "controlará" el valor tal cual. Esta acción interrumpirá la composición. Eso significa que no obtendremos el evento onCompositionEnd
...... (Si me equivoco, mencióname por favor.) Pero solo podemos cambiar el estado inmediatamente (De lo contrario, tendremos que enfrentar el problema @ Knubie menciona). Una reproducción aquí (parece un componente "medio controlado"): https://gist.github.com/cpdyj/6567437d96c315e9162778c8efdfb6e8
Pero estoy tan sorprendido de que el problema no tenga solución durante cinco años 😢
@hellendag Creo que no deberíamos disparar onChange hasta que se confirme la cadena IME.
No creo que esta sea una solución válida, ya que un componente podría querer conocer la cadena IME "no confirmada", por ejemplo, para filtrar opciones en una lista a medida que el usuario escribe.
No estoy seguro de si el enfoque que utilizo en este otro hilo podría ayudar a quienes tienen este problema, pero aquí hay un enlace por si acaso: https://github.com/facebook/react/issues/13104#issuecomment -691393940
¿alguna actualización?
Comentario más útil
Hola, chicos de Facebook, de hecho, este problema causa un problema SERIO : no podemos actualizar la entrada de forma asincrónica con la entrada china.
Por ejemplo, no podemos usar fuentes de datos reactivas a meteoritos o tiendas como redux, porque todos los comentarios se actualizan de forma asincrónica.
Aquí hay un ejemplo más simple para mostrar este problema, usa setTimeout para hacer una actualización asíncrona:
https://jsfiddle.net/liyatang/bq6oss6z/1/
Realmente espero que pueda solucionar esto rápidamente, para que no desperdiciemos esfuerzos para solucionarlo aquí y allá y una y otra vez.
Gracias.
Aquí está mi solución . Si alguien se enfrenta al mismo problema, puede echar un vistazo