Ich habe zwei TextInput-Felder wie folgt definiert:
<TextInput
style = {styles.titleInput}
returnKeyType = {"next"}
autoFocus = {true}
placeholder = "Title" />
<TextInput
style = {styles.descriptionInput}
multiline = {true}
maxLength = {200}
placeholder = "Description" />
Nachdem Sie auf der Tastatur die Schaltfläche "Weiter" gedrückt haben, springt meine reagierende Anwendung nicht zum zweiten TextInput-Feld. Wie kann ich das erreichen?
Vielen Dank!
Setzen Sie den zweiten TextInput
Fokus, wenn der TextInput
des vorherigen onSubmitEditing
ausgelöst wird.
Versuche dies
Hinzufügen eines Verweises zu zweiter Texteingangref={(input) => { this.secondTextInput = input; }}
Binden Sie die Fokusfunktion an das onSubmitEditing-Ereignis von first TextInput.onSubmitEditing={() => { this.secondTextInput.focus(); }}
Denken Sie daran, blurOnSubmit auf false zu setzen, um ein Flackern der Tastatur zu vermeiden.blurOnSubmit={false}
Wenn alles fertig ist, sollte es so aussehen.
<TextInput
placeholder = "FirstTextInput"
returnKeyType = { "next" }
onSubmitEditing={() => { this.secondTextInput.focus(); }}
blurOnSubmit={false}
/>
<TextInput
ref={(input) => { this.secondTextInput = input; }}
placeholder = "secondTextInput"
/>
Sie können dies tun, ohne refs zu verwenden. Dieser Ansatz wird bevorzugt, da Referenzen zu fragile Code führen können. Die React docs raten, wenn möglich andere Lösungen zu finden:
Wenn Sie nicht mehrere Apps mit React programmiert haben, wird Ihre erste Die Neigung besteht in der Regel darin, zu versuchen, Refs zu verwenden, um "Dinge zu machen. Wenn dies der Fall ist, nehmen Sie sich einen Moment Zeit und denken Sie mehr darüber nach kritisch darüber, wo sich der Staat in der Komponente befinden soll Hierarchie. Oft wird klar, dass der richtige Ort, um diese .__ zu "besitzen". Zustand ist auf einer höheren Ebene in der Hierarchie. Den Zustand dort setzen beseitigt oft den Wunsch, Refs zu verwenden, um "Dinge passieren zu lassen" – Stattdessen wird der Datenfluss normalerweise Ihr Ziel erreichen.
Stattdessen verwenden wir eine Zustandsvariable, um das zweite Eingabefeld zu fokussieren.
Fügen Sie eine Zustandsvariable hinzu, die wir der DescriptionInput
als Requisite übergeben:
initialState() {
return {
focusDescriptionInput: false,
};
}
Definieren Sie eine Handler-Methode, die diese Zustandsvariable auf true setzt:
handleTitleInputSubmit() {
this.setState(focusDescriptionInput: true);
}
Wenn Sie auf der Variablen TitleInput
Enter/next drücken, rufen wir handleTitleInputSubmit
auf. Dies setzt focusDescriptionInput
auf true.
<TextInput
style = {styles.titleInput}
returnKeyType = {"next"}
autoFocus = {true}
placeholder = "Title"
onSubmitEditing={this.handleTitleInputSubmit}
/>
Die Variable DescriptionInput
der Variable focus
ist auf unsere Zustandsvariable focusDescriptionInput
gesetzt. Wenn sich focusDescriptionInput
ändert (in Schritt 3), wird DescriptionInput
mit focus={true}
erneut gerendert.
<TextInput
style = {styles.descriptionInput}
multiline = {true}
maxLength = {200}
placeholder = "Description"
focus={this.state.focusDescriptionInput}
/>
Dies ist ein guter Weg, um die Verwendung von Refs zu vermeiden, da Refs zu fragilerem Code führen kann :)
EDIT: h/t an @LaneRettig für den Hinweis, dass Sie den React Native TextInput mit einigen hinzugefügten Requisiten und Methoden einpacken müssen, damit er auf focus
reagiert:
// Props:
static propTypes = {
focus: PropTypes.bool,
}
static defaultProps = {
focus: false,
}
// Methods:
focus() {
this._component.focus();
}
componentWillReceiveProps(nextProps) {
const {focus} = nextProps;
focus && this.focus();
}
Ab React Native 0.36 wird der Aufruf von focus()
(wie in mehreren anderen Antworten vorgeschlagen) für einen Texteingabeknoten nicht mehr unterstützt. Stattdessen können Sie das TextInputState
-Modul von React Native verwenden. Ich habe das folgende Hilfsmodul erstellt, um dies zu erleichtern:
// TextInputManager
//
// Provides helper functions for managing the focus state of text
// inputs. This is a hack! You are supposed to be able to call
// "focus()" directly on TextInput nodes, but that doesn't seem
// to be working as of ReactNative 0.36
//
import { findNodeHandle } from 'react-native'
import TextInputState from 'react-native/lib/TextInputState'
export function focusTextInput(node) {
try {
TextInputState.focusTextInput(findNodeHandle(node))
} catch(e) {
console.log("Couldn't focus text input: ", e.message)
}
}
Sie können dann die focusTextInput
-Funktion für jede "ref" einer TextInput
aufrufen. Zum Beispiel:
...
<TextInput onSubmit={() => focusTextInput(this.refs.inputB)} />
<TextInput ref="inputB" />
...
Ich habe eine kleine Bibliothek erstellt, die dies ausführt. Es ist keine Codeänderung erforderlich, außer die Umbruchansicht und den Import von TextInput zu ersetzen:
import { Form, TextInput } from 'react-native-autofocus'
export default () => (
<Form>
<TextInput placeholder="test" />
<TextInput placeholder="test 2" />
</Form>
)
https://github.com/zackify/react-native-autofocus
Ausführlich hier erklärt: https://zach.codes/autofocus-inputs-in-react-native/
Bei der Verwendung von react-native 0.45.1 sind auch Probleme beim Versuch aufgetreten, den Fokus auf ein Passwort zu setzen.
Nachdem ich die meisten der bestbewerteten Lösungen hier auf SO) ausprobiert hatte, fand ich eine Lösung für Github, die meine Anforderungen erfüllte: https://github.com/shoutem/ui/issues/ 44 # issuecomment-290724642
Etwas zusammenfassen:
import React, { Component } from 'react';
import { TextInput as RNTextInput } from 'react-native';
export default class TextInput extends Component {
render() {
const { props } = this;
return (
<RNTextInput
{...props}
ref={(input) => props.inputRef && props.inputRef(input)}
/>
);
}
}
Und dann benutze ich es so:
import React, {Component} from 'react';
import {
View,
} from 'react-native';
import TextInput from "../../components/TextInput";
class Login extends Component {
constructor(props) {
super(props);
this.passTextInput = null
}
render() {
return (
<View style={{flex:1}}>
<TextInput
style={{flex:1}}
placeholder="Username"
onSubmitEditing={(event) => {
this.passTextInput.focus()
}}
/>
<TextInput
style={{flex:1}}
placeholder="Password"
inputRef={(input) => {
this.passTextInput = input
}}
/>
</View>
)
}
}
Wenn Sie tcomb-form-native
so wie ich bin, können Sie dies auch tun. Hier ist der Trick: Anstatt die Requisiten der TextInput
direkt einzustellen, tun Sie dies über options
. Sie können sich auf die Felder des Formulars beziehen als:
this.refs.form.getComponent('password').refs.input.focus()
Das Endprodukt sieht also ungefähr so aus:
var t = require('tcomb-form-native');
var Form = t.form.Form;
var MyForm = t.struct({
field1: t.String,
field2: t.String,
});
var MyComponent = React.createClass({
_getFormOptions () {
return {
fields: {
field1: {
returnKeyType: 'next',
onSubmitEditing: () => {this.refs.form.getComponent('field2').refs.input.focus()},
},
},
};
},
render () {
var formOptions = this._getFormOptions();
return (
<View style={styles.container}>
<Form ref="form" type={MyForm} options={formOptions}/>
</View>
);
},
});
(Dank an remcoanker für die Veröffentlichung der Idee: https://github.com/gcanti/tcomb-form-native/issues/96 )
Für mich auf RN 0.50.3 ist dies auf folgende Weise möglich:
<TextInput
autoFocus={true}
onSubmitEditing={() => {this.PasswordInputRef._root.focus()}}
/>
<TextInput ref={input => {this.PasswordInputRef = input}} />
Sie müssen this.PasswordInputRef. _root . Focus () sehen.
So habe ich es erreicht. Das folgende Beispiel hat die in React 16.3 eingeführte React.createRef () - API verwendet.
class Test extends React.Component {
constructor(props) {
super(props);
this.secondTextInputRef = React.createRef();
}
render() {
return(
<View>
<TextInput
placeholder = "FirstTextInput"
returnKeyType="next"
onSubmitEditing={() => { this.secondTextInputRef.current.focus(); }}
/>
<TextInput
ref={this.secondTextInputRef}
placeholder = "secondTextInput"
/>
</View>
);
}
}
Ich denke das wird dir helfen.
Callback-Refs anstelle der Legacy String-Refs verwenden:
<TextInput
style = {styles.titleInput}
returnKeyType = {"next"}
autoFocus = {true}
placeholder = "Title"
onSubmitEditing={() => {this.nextInput.focus()}}
/>
<TextInput
style = {styles.descriptionInput}
multiline = {true}
maxLength = {200}
placeholder = "Description"
ref={nextInput => this.nextInput = nextInput}
/>
Versuchen Sie diese Lösung bei GitHub-Problemen von React Native.
https://github.com/facebook/react-native/pull/2149#issuecomment-129262565
Sie müssen das ref prop für die TextInput-Komponente verwenden.
Dann benötigen Sie eine Funktion, die für onSubmitEditing prop aufgerufen wird und den Fokus auf den zweiten TextInput-Ref verlagert.
var InputScreen = React.createClass({
_focusNextField(nextField) {
this.refs[nextField].focus()
},
render: function() {
return (
<View style={styles.container}>
<TextInput
ref='1'
style={styles.input}
placeholder='Normal'
returnKeyType='next'
blurOnSubmit={false}
onSubmitEditing={() => this._focusNextField('2')}
/>
<TextInput
ref='2'
style={styles.input}
keyboardType='email-address'
placeholder='Email Address'
returnKeyType='next'
blurOnSubmit={false}
onSubmitEditing={() => this._focusNextField('3')}
/>
<TextInput
ref='3'
style={styles.input}
keyboardType='url'
placeholder='URL'
returnKeyType='next'
blurOnSubmit={false}
onSubmitEditing={() => this._focusNextField('4')}
/>
<TextInput
ref='4'
style={styles.input}
keyboardType='numeric'
placeholder='Numeric'
blurOnSubmit={false}
onSubmitEditing={() => this._focusNextField('5')}
/>
<TextInput
ref='5'
style={styles.input}
keyboardType='numbers-and-punctuation'
placeholder='Numbers & Punctuation'
returnKeyType='done'
/>
</View>
);
}
});
Damit die akzeptierte Lösung funktioniert, wenn sich Ihre TextInput
in einer anderen Komponente befindet, müssen Sie die Referenz von ref
in den übergeordneten Container platzieren.
// MyComponent
render() {
<View>
<TextInput ref={(r) => this.props.onRef(r)} { ...this.props }/>
</View>
}
// MyView
render() {
<MyComponent onSubmitEditing={(evt) => this.myField2.focus()}/>
<MyComponent onRef={(r) => this.myField2 = r}/>
}
Mein Szenario ist <CustomBoladonesTextInput /> Ein RN umschließen <TextInput /> .
Ich habe dieses Problem wie folgt gelöst:
Mein Formular sieht so aus:
<CustomBoladonesTextInput
onSubmitEditing={() => this.customInput2.refs.innerTextInput2.focus()}
returnKeyType="next"
... />
<CustomBoladonesTextInput
ref={ref => this.customInput2 = ref}
refInner="innerTextInput2"
... />
In der Komponentendefinition von CustomBoladonesTextInput übergebe ich das refField wie folgt an den inneren Ref-Prop:
export default class CustomBoladonesTextInput extends React.Component {
render() {
return (< TextInput ref={this.props.refInner} ... />);
}
}
Und voila. Alles wieder funktionsfähig. Hoffe das hilft
<TextInput placeholder="Nombre"
ref="1"
editable={true}
returnKeyType="next"
underlineColorAndroid={'#4DB6AC'}
blurOnSubmit={false}
value={this.state.First_Name}
onChangeText={First_Name => this.setState({ First_Name })}
onSubmitEditing={() => this.focusNextField('2')}
placeholderTextColor="#797a7a" style={{ marginBottom: 10, color: '#808080', fontSize: 15, width: '100%', }} />
<TextInput placeholder="Apellido"
ref="2"
editable={true}
returnKeyType="next"
underlineColorAndroid={'#4DB6AC'}
blurOnSubmit={false}
value={this.state.Last_Name}
onChangeText={Last_Name => this.setState({ Last_Name })}
onSubmitEditing={() => this.focusNextField('3')}
placeholderTextColor="#797a7a" style={{ marginBottom: 10, color: '#808080', fontSize: 15, width: '100%', }} />
und Methode hinzufügen
focusNextField(nextField) {
this.refs[nextField].focus();
}
Es gibt eine Möglichkeit, tabs in einer TextInput
zu erfassen. Es ist hackig, aber besser als nichts .
Definieren Sie einen onChangeText
-Handler, der den neuen Eingabewert mit dem alten vergleicht und nach einem \t
sucht. Wenn eines gefunden wird, bewegen Sie das Feld wie von @boredgames gezeigt vor
Wenn die Variable username
den Wert für den Benutzernamen enthält und setUsername
eine Aktion auslöst, um sie im Speicher (Komponentenstatus, Redux-Store usw.) zu ändern, gehen Sie folgendermaßen vor:
function tabGuard (newValue, oldValue, callback, nextCallback) {
if (newValue.indexOf('\t') >= 0 && oldValue.indexOf('\t') === -1) {
callback(oldValue)
nextCallback()
} else {
callback(newValue)
}
}
class LoginScene {
focusNextField = (nextField) => {
this.refs[nextField].focus()
}
focusOnPassword = () => {
this.focusNextField('password')
}
handleUsernameChange = (newValue) => {
const { username } = this.props // or from wherever
const { setUsername } = this.props.actions // or from wherever
tabGuard(newValue, username, setUsername, this.focusOnPassword)
}
render () {
const { username } = this.props
return (
<TextInput ref='username'
placeholder='Username'
autoCapitalize='none'
autoCorrect={false}
autoFocus
keyboardType='email-address'
onChangeText={handleUsernameChange}
blurOnSubmit={false}
onSubmitEditing={focusOnPassword}
value={username} />
)
}
}
in Ihrer Komponente:
constructor(props) {
super(props);
this.focusNextField = this
.focusNextField
.bind(this);
// to store our input refs
this.inputs = {};
}
focusNextField(id) {
console.log("focus next input: " + id);
this
.inputs[id]
._root
.focus();
}
Hinweis: Ich habe ._root
verwendet, da es sich um einen Bezug zu TextInput in NativeBase'Library 'handelt. Eingabe
und in Ihren Texteingaben so
<TextInput
onSubmitEditing={() => {
this.focusNextField('two');
}}
returnKeyType="next"
blurOnSubmit={false}/>
<TextInput
ref={input => {
this.inputs['two'] = input;
}}/>
Wenn Sie NativeBase als UI-Komponenten verwenden, können Sie dieses Beispiel verwenden
<Item floatingLabel>
<Label>Title</Label>
<Input
returnKeyType = {"next"}
autoFocus = {true}
onSubmitEditing={(event) => {
this._inputDesc._root.focus();
}}
/>
</Item>
<Item floatingLabel>
<Label>Description</Label>
<Input
getRef={(c) => this._inputDesc = c}
multiline={true} style={{height: 100}} />
onSubmitEditing={(event) => { this._inputLink._root.focus(); }}
</Item>```
Hier eine Reagenzlösung für eine Eingabekomponente mit der Eigenschaft: focus.
Das Feld wird so lange fokussiert, wie diese Stütze auf wahr gesetzt ist, und nicht fokussiert sein, solange dies falsch ist.
Leider muss für diese Komponente ein: ref definiert sein. Ich konnte keine andere Möglichkeit finden, .focus () darauf aufzurufen. Ich freue mich über Vorschläge.
(defn focusable-input [init-attrs]
(r/create-class
{:display-name "focusable-input"
:component-will-receive-props
(fn [this new-argv]
(let [ref-c (aget this "refs" (:ref init-attrs))
focus (:focus (ru/extract-props new-argv))
is-focused (.isFocused ref-c)]
(if focus
(when-not is-focused (.focus ref-c))
(when is-focused (.blur ref-c)))))
:reagent-render
(fn [attrs]
(let [init-focus (:focus init-attrs)
auto-focus (or (:auto-focus attrs) init-focus)
attrs (assoc attrs :auto-focus auto-focus)]
[input attrs]))}))
https://Gist.github.com/Knotschi/6f97efe89681ac149113ddec4c396cc5