¿Cómo escucho el cambio de evento para el contentEditablecontrol basado en?
var Number = React.createClass({
render: function() {
return <div>
<span contentEditable={true} onChange={this.onChange}>
{this.state.value}
</span>
=
{this.state.value}
</div>;
},
onChange: function(v) {
// Doesn't fire :(
console.log('changed', v);
},
getInitialState: function() {
return {value: '123'}
}
});
React.renderComponent(<Number />, document.body);

initialValueenstatey lo uso enrender, pero no dejo Reaccionar actualización aún más.contentEditablecambio de mi enfoque, en lugar de unspanoparagraph, he usado uninputjunto con sureadonlyatributo.Respuestas:
Editar: vea la respuesta de Sebastien Lorber que corrige un error en mi implementación.
Utilice el evento onInput y, opcionalmente, onBlur como respaldo. Es posible que desee guardar el contenido anterior para evitar enviar eventos adicionales.
Personalmente tendría esto como mi función de renderizado.
jsbin
Que usa este simple contenedor alrededor de contentEditable.
fuente
this.setState({html: "something not in the editable div"}})this.getDOMNode().innerHTMLenshouldComponentUpdateno está muy optimizado derechastate.htmlel último valor "conocido", React no actualizará el DOM porque el nuevo html es exactamente el mismo en lo que respecta a React (aunque el DOM real es diferente). Consulte jsfiddle . No he encontrado una buena solución para esto, por lo que cualquier idea es bienvenida.shouldComponentUpdatedebe ser puro (no tener efectos secundarios).Editar 2015
Alguien ha hecho un proyecto en NPM con mi solución: https://github.com/lovasoa/react-contenteditable
Edición 06/2016: Acabo de encontrar un nuevo problema que ocurre cuando el navegador intenta "reformatear" el html que le acaba de dar, lo que lleva a que el componente siempre vuelva a renderizarse. Ver
Edición 07/2016: aquí está mi contenido de producción Implementación editable. Tiene algunas opciones adicionales sobre las
react-contenteditableque quizás desee, que incluyen:Resumen:
La solución de FakeRainBrigand me ha funcionado bastante bien durante algún tiempo hasta que tuve nuevos problemas. ContentEditables son una molestia, y no son realmente fáciles de manejar con React ...
Este JSFiddle demuestra el problema.
Como puede ver, cuando escribe algunos caracteres y hace clic en
Clear, el contenido no se borra. Esto se debe a que intentamos restablecer el contenteditable al último valor de dom virtual conocido.Entonces parece que:
shouldComponentUpdateevitar los saltos de posición del cursorshouldComponentUpdateesta manera.Por lo tanto, necesita una línea adicional para que, siempre que
shouldComponentUpdatedevuelva sí, esté seguro de que el contenido DOM está realmente actualizado.Entonces, la versión aquí agrega ay se
componentDidUpdateconvierte en:El dom virtual permanece desactualizado y puede que no sea el código más eficiente, pero al menos funciona :) Mi error está resuelto
Detalles:
1) Si pones shouldComponentUpdate para evitar saltos de intercalación, entonces el contenteditable nunca se vuelve a reproducir (al menos en las pulsaciones de teclas)
2) Si el componente nunca se vuelve a reproducir con la pulsación de una tecla, React mantiene un dom virtual obsoleto para este contenteditable.
3) Si React mantiene una versión desactualizada de contenteditable en su árbol de dom virtual, entonces si intenta restablecer el contenteditable al valor desactualizado en el dom virtual, entonces durante la diferencia de dom virtual, React calculará que no hay cambios en aplicar al DOM!
Esto sucede principalmente cuando:
fuente
{...this.props}que lo uses para que el cliente pueda personalizar este comportamiento desde afuerashouldComponentUpdatecódigo previene los saltos de intercalación?Esta es la solución más simple que funcionó para mí.
fuente
onInputcomo se indica en el ejemplo.Probablemente esta no sea exactamente la respuesta que está buscando, pero habiendo luchado con esto yo mismo y teniendo problemas con las respuestas sugeridas, decidí hacerlo sin control.
Cuando
editablees propfalse, utilizotextprop tal como está, pero cuando lo estátrue, cambio al modo de edición en el quetextno tiene ningún efecto (pero al menos el navegador no se asusta). Durante este tiempoonChangeson disparados por el control. Finalmente, cuando vuelvo a cambiareditableafalse, llena HTML con lo que se pasótext:fuente
shouldComponentUpdatetan fácilmente, por lo que ya no me salva de los saltos de intercalación. Finalmente, tengo:empty:beforemarcadores de posición de pseudoelementos CSS, pero estashouldComponentUpdateimplementación impidió que FF y Safari limpiaran el campo cuando el usuario lo borraba. Tardé 5 horas en darme cuenta de que puedo eludir todos estos problemas con la CE incontrolada.editableenUncontrolledContentEditable. ¿Podría proporcionar un ejemplo ejecutable?editabledesde afuera. Piense en un campo que se puede editar en línea cuando el usuario presiona "Editar" y debería ser de nuevo de solo lectura cuando el usuario presiona "Guardar" o "Cancelar". Entonces, cuando es de solo lectura, uso accesorios, pero dejo de mirarlos cada vez que entro en el "modo de edición" y solo miro los accesorios nuevamente cuando salgo de él.escapeTextForBrowserde nombre aescapeTextContentForBrowser.Dado que cuando se completa la edición, el enfoque del elemento siempre se pierde, simplemente puede usar el gancho onBlur.
fuente
Sugiero usar un mutationObserver para hacer esto. Te da mucho más control sobre lo que está sucediendo. También le brinda más detalles sobre cómo el navegador interpreta todas las pulsaciones de teclas
Aquí en TypeScript
fuente
Aquí hay un componente que incorpora mucho de esto por lovasoa: https://github.com/lovasoa/react-contenteditable/blob/master/index.js
Calza el evento en el emisChange
Estoy usando un enfoque similar con éxito
fuente