zurb foundation - Cómo hacer que reaccion.js juegue bien junto con zurb revela la forma modal
zurb-foundation reactjs (2)
Estoy tratando de integrar la revelación de zurb con la forma en el componente reaccionar. Hasta ahora, el siguiente código muestra correctamente el formulario modal:
ModalForm = React.createClass({
handleSubmit: function(attrs) {
this.props.onSubmit(attrs);
return false;
},
render: function(){
return(
<div>
<a href="#" data-reveal-id="formModal" className="button">Add new</a>
<div id="formModal" className="reveal-modal" data-reveal>
<h4>Add something new</h4>
<Form onSubmit={this.handleSubmit} />
<a className="close-reveal-modal">×</a>
</div>
</div>
);
}
});
El componente de Form
es bastante estándar:
Form = React.createClass({
handleSubmit: function() {
var body = this.refs.body.getDOMNode().value.trim();
if (!body) {
return false;
}
this.props.onSubmit({body: body});
this.refs.body.getDOMNode().value = '''';
return false;
},
render: function(){
return(
<form onSubmit={this.handleSubmit}>
<textarea name="body" placeholder="Say something..." ref="body" />
<input type="submit" value="Send" className="button" />
</form>
);
}
});
Problema: cuando represento el componente de formulario dentro del componente de formulario modal y escribo algo en la entrada de formulario, veo en la consola de excepción el Uncaught object
Esta es una pila:
Uncaught object
invariant
ReactMount.findComponentRoot
ReactMount.findReactNodeByID
getNode
...
Si simplemente represento el componente de formulario directamente en el componente principal, entonces todo funciona. ¿Alguien podría ayudar por favor?
Aquí es cómo hacer lo que Mike hizo, pero usando un modal de zf reveal:
var Dialog = React.createClass({
statics: {
open: function(){
this.$dialog = $(''#my-dialog'');
if (!this.$dialog.length) {
this.$dialog = $(''<div id="my-dialog" class="reveal-modal" data-reveal role="dialog"></div>'')
.appendTo(''body'');
}
this.$dialog.foundation(''reveal'', ''open'');
return React.render(
<Dialog close={this.close.bind(this)}/>,
this.$dialog[0]
);
},
close: function(){
if(!this.$dialog || !this.$dialog.length) {
return;
}
React.unmountComponentAtNode(this.$dialog[0]);
this.$dialog.foundation(''reveal'', ''close'');
},
},
render : function() {
return (
<div>
<h1>This gets rendered into the modal</h1>
<a href="#" className="button" onClick={this.props.close}>Close</a>
</div>
);
}
});
En resumen, estás haciendo esto mal y esto no es un error al reaccionar.
Si utiliza cualquier tipo de complemento que modifique los nodos de dominio del componente de reacción, se romperán las cosas de una forma u otra.
Lo que debería hacer en su lugar es utilizar reaccionar, y css complementario, para colocar el componente de la forma que le gustaría para su diálogo modal.
Yo sugeriría crear un componente que use la propiedad del componente statics
de react para definir un par de funciones que envuelvan renderComponent
para darle una llamada de función limpia y agradable para mostrar u ocultar un diálogo de reacción. Aquí hay un ejemplo reducido de algo que he usado en el pasado. NB: utiliza jQuery, pero puede reemplazar el jQ con las llamadas elementById
api estándar a elementos como elementById
y etc. si no desea el código jQuery.
window.MyDialog = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
content: React.PropTypes.string.isRequired
},
statics: {
// open a dialog with props object as props
open: function(props) {
var $anchor = $(''#dialog-anchor'');
if (!$anchor.length) {
$anchor = $(''<div></div>'')
.prop(''id'', ''dialog-anchor'');
.appendTo(''body'');
}
return React.renderComponent(
MyDialog(props),
$anchor.get(0)
);
},
// close a dialog
close: function() {
React.unmountComponentAtNode($(''#dialog-anchor'').get(0));
}
},
// when dialog opens, add a keyup event handler to body
componentDidMount: function() {
$(''body'').on(''keyup.myDialog'', this.globalKeyupHandler);
},
// when dialog closes, clean up the bound keyup event handler on body
componentWillUnmount: function() {
$(''body'').off(''keyup.myDialog'');
},
// handles keyup events on body
globalKeyupHandler: function(e) {
if (e.keyCode == 27) { // ESC key
// close the dialog
this.statics.close();
}
},
// Extremely basic dialog dom layout - use your own
render: function() {
<div className="dialog">
<div className="title-bar">
<div className="title">{this.props.title}</div>
<a href="#" className="close" onClick={this.closeHandler}>
</div>
</div>
<div className="content">
{this.props.content}
</div>
</div>
}
});
Luego abres un diálogo llamando a:
MyDialog.open({title: ''Dialog Title'', content: ''My dialog content''});
Y cerrarla con
MyDialog.close()
El diálogo siempre se adjunta a un nuevo nodo dom directamente debajo del cuerpo con id ''dialog-anchor''. Si abre un cuadro de diálogo cuando ya hay uno abierto, simplemente actualizará el dominio en función de los nuevos accesorios (o no si son iguales).
Por supuesto, pasar el contenido del diálogo como un argumento props no es particularmente útil. Por lo general, me extiendo a continuación para analizar markdown -> html para el contenido u obtener algo de html a través de una solicitud ajax dentro del componente al proporcionar una URL como prop.
Sé que el código anterior no es exactamente lo que buscabas, pero no creo que haya una buena manera de hacer que un complemento modificador de dominación funcione. Nunca se puede asumir que la representación de dominio del componente de reacción es estática y, por lo tanto, no puede ser manipulada por un complemento de terceros con éxito. Honestamente, creo que si desea utilizar reaccionar de esta manera, debería volver a evaluar por qué está utilizando el marco.
Dicho esto, creo que el código anterior es un excelente punto de partida para un diálogo en el que toda la manipulación se produce dentro del componente, ¡lo que después es de lo que se trata reactjs!
NB: el código se escribió muy rápidamente desde la memoria y en realidad no se probó en su forma actual, lo siento si hay algunos errores de sintaxis menores o algo así.