Wie man reactive.js zusammen mit zurb machen kann, zeigt Modalform - zurb-foundation, reactjs, react-jsx, zurb-reveal

Ich versuche zub reve mit der Form in die react Komponente zu integrieren. Bis jetzt zeigt der nächste Code die modale Form richtig an:

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">&#215;</a>
</div>
</div>
);
}
});

Das Form Komponente ist ziemlich Standard:

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>
);
}
});

Problem: Wenn ich Formularkomponente innerhalb der modalen Formularkomponente rendere und etwas in Formulareingabe eintrage, sehe ich in der Konsolenausnahme Uncaught object. Das ist ein Stapel:

Uncaught object
invariant
ReactMount.findComponentRoot
ReactMount.findReactNodeByID
getNode
...

Wenn ich Formularkomponente direkt in der übergeordneten Komponente rendere, funktioniert alles. Könnte jemand bitte helfen?

Antworten:

12 für die Antwort № 1

Kurz gesagt, du machst das falsch und das ist es nicht ein Fehler in der Reaktion.

Wenn Sie irgendeine Art von Plugin verwenden, das die Dom-Knoten der reaktiven Komponente modifiziert, dann wird es die Dinge auf die eine oder andere Weise brechen.

Was Sie stattdessen tun sollten, ist die Verwendung von react selbst und komplementären CSS, um die Komponente so zu positionieren, wie Sie es für Ihren modalen Dialog wünschen.

Ich würde vorschlagen, eine Komponente zu erstellen, die reacts verwendet statics Komponenteneigenschaft, um einige Funktionen für das Wrapping zu definieren renderComponent um Ihnen einen netten, sauberen Funktionsanruf zu geben, odereinen Reaktivdialog ausblenden Hier ist ein reduziertes Beispiel für etwas, das ich in der Vergangenheit benutzt habe. NB: Es verwendet jQuery, aber Sie könnten das jQ durch Standard-js-API-Aufrufe zu Dingen wie ersetzen elementById und etc, wenn Sie den jQuery-Code nicht wollen.

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>
}
});

Sie öffnen dann einen Dialog durch Aufruf von:

MyDialog.open({title: "Dialog Title", content: "My dialog content"});

Und schließe es mit

MyDialog.close()

Der Dialog hängt immer an einen neuen Domänenknoten andirekt unter dem Körper mit der ID "dialog-anchor". Wenn Sie einen Dialog öffnen, wenn einer bereits geöffnet ist, aktualisiert er einfach den Dom basierend auf neuen Requisiten (oder nicht, wenn sie identisch sind).

Übergeben Sie den Inhalt des Dialogs natürlich alsRequisiten Argument ist nicht besonders nützlich. Ich in der Regel unten entweder Parsen Markdown -> html für den Inhalt oder erhalten Sie HTML über eine Ajax Anfrage innerhalb der Komponente bei der Bereitstellung einer URL als Prop statt.

Ich weiß, dass der obige Code nicht genau das ist, was du warstauf der Suche nach, aber ich glaube nicht, es gibt einen guten Weg, um ein dom-modifizierendes Plugin mit reagieren zu arbeiten. Sie können niemals davon ausgehen, dass die dom-Repräsentation der reaktiven Komponente statisch ist und daher nicht von einem 3rd-Party-Plugin manipuliert werden kann. Ich denke ehrlich, wenn Sie auf diese Weise reagieren wollen, sollten Sie neu bewerten, warum Sie es sind das Framework verwenden.

Das heißt, ich denke, dass der obige Code ein guter Ausgangspunkt für einen Dialog ist, in dem alle Manipulationen innerhalb der Komponente stattfinden, was schließlich alles ist, worum es bei reactjs geht!

NB: Code wurde sehr schnell aus dem Speicher geschrieben und nicht wirklich in seiner aktuellen Form getestet, also tut es leid, wenn es kleinere Syntaxfehler oder so etwas gibt.


5 für die Antwort № 2

Hier ist, wie man macht, was Mike getan hat, aber mit einem ZF Reveal Modal:

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>
);
}
});

Am beliebtesten