Ich schreibe nur zur Texteingabe und onChange
falls ich setState
anrufe, rendert React meine Benutzeroberfläche erneut. Das Problem ist, dass die Texteingabe immer einen Fokus verliert, daher muss ich sie für jeden Buchstaben erneut fokussieren: D.
var EditorContainer = React.createClass({
componentDidMount: function () {
$(this.getDOMNode()).slimScroll({height: this.props.height, distance: '4px', size: '8px'});
},
componentDidUpdate: function () {
console.log("zde");
$(this.getDOMNode()).slimScroll({destroy: true}).slimScroll({height: 'auto', distance: '4px', size: '8px'});
},
changeSelectedComponentName: function (e) {
//this.props.editor.selectedComponent.name = $(e.target).val();
this.props.editor.forceUpdate();
},
render: function () {
var style = {
height: this.props.height + 'px'
};
return (
<div className="container" style={style}>
<div className="row">
<div className="col-xs-6">
{this.props.selected ? <h3>{this.props.selected.name}</h3> : ''}
{this.props.selected ? <input type="text" value={this.props.selected.name} onChange={this.changeSelectedComponentName} /> : ''}
</div>
<div className="col-xs-6">
<ComponentTree editor={this.props.editor} components={this.props.components}/>
</div>
</div>
</div>
);
}
});
javascript
reactjs
Krabben
quelle
quelle
Antworten:
Ohne den Rest Ihres Codes zu sehen, ist dies eine Vermutung. Geben Sie beim Erstellen eines EditorContainers einen eindeutigen Schlüssel für die Komponente an:
<EditorContainer key="editor1"/>
Wenn beim erneuten Rendern derselbe Schlüssel angezeigt wird, wird React angezeigt, dass die Ansicht nicht überlastet und neu generiert, sondern erneut verwendet wird. Dann sollte das fokussierte Objekt den Fokus behalten.
quelle
Ich komme immer wieder hierher zurück und finde am Ende immer die Lösung für mein anderswo. Also werde ich es hier dokumentieren, weil ich weiß, dass ich das wieder vergessen werde!
Der Grund
input
dafür, dass ich in meinem Fall den Fokus verlor, war die Tatsache, dass ich den Statuswechsel erneut renderteinput
.Buggy Code:
Das Problem ist also, dass ich immer anfange, alles an einem Ort zu codieren, um es schnell zu testen und später in separate Module aufzuteilen. Hier schlägt diese Strategie jedoch fehl, da das Aktualisieren des Status bei Eingabeänderungen die Renderfunktion auslöst und der Fokus verloren geht.
Fix ist einfach, machen Sie die Modularisierung von Anfang an, mit anderen Worten: "Verschieben Sie die
Input
Komponente aus derrender
Funktion".Fester Code
Ref. zur Lösung: https://github.com/styled-components/styled-components/issues/540#issuecomment-283664947
quelle
render()
undclass ... extends Component
aufgrund des Verweises auf zu verschiebenthis
. zBonChange={this.handleInputChange}
render
Funktion, für React-Funktionskomponenten keine Komponenten im Funktionskörper.render
Funktion die Methode 'this.handleChange' auf und übergibt die zu verwendenden Komponenten. ZBconst TextAreaDataField = TextAreaDataFieldFactory(this.handleChange)
. Ich habe die Komponentenerstellung einfach in den Konstruktor verschoben und in derrender
Methode als auf sie zugegriffenthis.TextAreaDataField
. Lief wie am Schnürchen.Wenn es sich um ein Problem innerhalb eines Reaktionsrouters handelt,
<Route/>
verwenden Sierender
stattdessen die Requisitecomponent
.Der Fokusverlust tritt auf, weil die
component
RequisiteReact.createElement
jedes Mal verwendet wird, anstatt nur die Änderungen neu zu rendern.Details hier: https://reacttraining.com/react-router/web/api/Route/component
quelle
<Route component={() => <MyComponent/>} />
wenn ich es hätte tun sollen<Route component={MyComponent} />
Meine Antwort ähnelt der von @ z5h.
In meinem Fall habe ich
Math.random()
ein eindeutiges Elementkey
für die Komponente generiert .Ich dachte, das
key
wird nur zum Auslösen eines erneuten Renderns für diese bestimmte Komponente verwendet, anstatt alle Komponenten in diesem Array neu zu rendern (ich gebe ein Array von Komponenten in meinem Code zurück). Ich wusste nicht, dass es zum Wiederherstellen des Zustands nach dem erneuten Rendern verwendet wird.Das zu entfernen hat den Job für mich erledigt.
quelle
Das Anwenden des
autoFocus
Attributs auf dasinput
Element kann als Problemumgehung in Situationen dienen, in denen nur eine Eingabe fokussiert werden muss. In diesem Fall wäre einkey
Attribut nicht erforderlich, da es sich nur um ein Element handelt und Sie sich darüber hinaus keine Sorgen machen müssen, dasinput
Element in eine eigene Komponente zu zerlegen, um nicht den Fokus auf das erneute Rendern der Hauptkomponente zu verlieren.quelle
Ich habe das gleiche Verhalten.
Das Problem in meinem Code war, dass ich ein verschachteltes Array von jsx-Elementen wie folgt erstellt habe:
Jedes Element in diesem verschachtelten Array wird jedes Mal neu gerendert, wenn ich das übergeordnete Element aktualisiert habe. Und so verlieren die Eingänge dort jedes Mal "ref" prop
Ich habe das Problem behoben, indem das innere Array in eine Reaktionskomponente umgewandelt wurde (eine Funktion mit einer Renderfunktion).
BEARBEITEN:
Das gleiche Problem tritt auf, wenn ich ein verschachteltes baue
React.Fragment
quelle
Ich bin gerade auf dieses Problem gestoßen und bin hierher gekommen, um Hilfe zu holen. Überprüfen Sie Ihr CSS! Das Eingabefeld kann nicht haben
user-select: none;
oder es funktioniert nicht auf einem iPad.quelle
Ich habe das gleiche Problem gelöst, indem ich das Schlüsselattribut in der Eingabe und seine übergeordneten Elemente gelöscht habe
quelle
Für mich wurde dies dadurch verursacht, dass das Eingabefeld für die Suche in derselben Komponente (UserList) wie die Liste der Suchergebnisse gerendert wurde . Wenn sich also die Suchergebnisse änderten, wurde die gesamte UserList-Komponente einschließlich des Eingabefelds erneut gerendert.
Meine Lösung bestand darin, eine ganz neue Komponente namens UserListSearch zu erstellen, die von UserList getrennt ist . Ich musste keine Schlüssel für die Eingabefelder in UserListSearch festlegen, damit dies funktioniert. Die Renderfunktion meines UsersContainer sieht nun folgendermaßen aus:
Hoffentlich hilft das auch jemandem.
quelle
Befindet sich das Eingabefeld in einem anderen Element (dh einem Containerelement wie
<div key={"bart"}...><input key={"lisa"}...> ... </input></div>
- die Ellipsen hier zeigen ausgelassenen Code an), muss auf dem Containerelement (sowie auf dem Eingabefeld) ein eindeutiger und konstanter Schlüssel vorhanden sein . Andernfalls rendert React ein brandneues Containerelement, wenn der Status des Kindes aktualisiert wird, anstatt nur den alten Container neu zu rendern. Logischerweise sollte nur das untergeordnete Element aktualisiert werden, aber ...Ich hatte dieses Problem beim Versuch, eine Komponente zu schreiben, die eine Reihe von Adressinformationen enthielt. Der Arbeitscode sieht so aus
Scharfäugige Leser werden feststellen, dass dies
<fieldset>
ein enthaltendes Element ist, für das jedoch kein Schlüssel erforderlich ist. Das gleiche gilt für<>
und<React.Fragment>
oder sogar<div>
warum? Vielleicht braucht nur der unmittelbare Container einen Schlüssel. Ich weiß nicht. Wie Mathematiklehrbücher sagen, bleibt die Erklärung dem Leser als Übung überlassen.quelle
Der Hauptgrund ist: Wenn React erneut gerendert wird, ist Ihre vorherige DOM-Referenz ungültig. Dies bedeutet, dass durch Reagieren der DOM-Baum geändert wurde und Sie this.refs.input.focus nicht funktionieren, da die Eingabe hier nicht mehr vorhanden ist.
quelle
Die Antworten haben mir nicht geholfen, hier ist, was ich getan habe, aber ich hatte eine einzigartige Situation.
Um den Code zu bereinigen, verwende ich normalerweise dieses Format, bis ich bereit bin, die Komponente in eine andere Datei zu ziehen.
Dies führte jedoch dazu, dass der Fokus verloren ging, als ich den Code direkt in das Div einfügte, in dem es funktionierte.
Ich weiß nicht, warum das so ist, dies ist das einzige Problem, das ich beim Schreiben auf diese Weise hatte, und ich mache es in den meisten Dateien, die ich habe, aber wenn jemand etwas Ähnliches tut, verliert es deshalb den Fokus.
quelle
Ich hatte das gleiche Problem mit einer HTML-Tabelle, in der ich Textzeilen in einer Spalte eingegeben habe. Innerhalb einer Schleife lese ich ein JSON-Objekt und erstelle Zeilen. Insbesondere habe ich eine Spalte mit Eingabetext.
http://reactkungfu.com/2015/09/react-js-loses-input-focus-on-typing/
Ich habe es auf folgende Weise gelöst
quelle
Es stellte sich heraus, dass ich
this
an die Komponente gebunden war, wodurch sie erneut gerendert wurde.Ich dachte, ich würde es hier posten, falls jemand anderes dieses Problem hätte.
Ich musste mich ändern
Zu
Einfache Lösung , da in meinem Fall, ich habe nicht wirklich brauchte
this
inrenderField
, aber hoffentlich Posting ich dies helfen wird , jemand anderes.quelle
Ich wechselte die
value
Requisite zudefaultValue
. Das ist für mich in Ordnung.quelle
Mein Problem war, dass ich meinen Schlüssel dynamisch mit einem Wert des Elements benannte, in meinem Fall "Name", also war der Schlüssel key = {
${item.name}-${index}
}. Wenn ich also die Eingabe mit item.name als Wert ändern wollte, änderte sich auch der Schlüssel und die Reaktion erkannte dieses Element nichtquelle
Ich hatte dieses Problem und es stellte sich heraus, dass ich eine funktionale Komponente verwendete und mich mit dem Status einer übergeordneten Komponente verband. Wenn ich zur Verwendung einer Klassenkomponente wechselte, verschwand das Problem. Hoffentlich gibt es einen Weg, dies zu umgehen, wenn funktionale Komponenten verwendet werden, da dies für einfache Item-Renderer et al. Viel bequemer ist.
quelle
hat den nächsten Code in die Tag-Eingabe aufgenommen:
Vor:
Nach dem:
quelle