Native reagieren: Wie wähle ich den nächsten TextInput aus, nachdem ich die Tastaturtaste „Weiter“ gedrückt habe?

201

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" />

Nach dem Drücken der Schaltfläche "Weiter" auf meiner Tastatur springt meine reaktionsnative App jedoch nicht zum zweiten TextInput-Feld. Wie kann ich das erreichen?

Vielen Dank!

andreaswienes
quelle
Mitch's Antwort (derzeit die dritte unten) funktioniert für mich auf v0.42.
Lawrence
Für Leute auf React v16.8.0oder höher würde ich die Antwort von @Eli Johnson unten empfehlen. React hat viele Verwendungen der refin den folgenden Lösungen bereitgestellten abgelehnt .
thedeg123

Antworten:

331

Stellen Sie den zweiten TextInputFokus, wenn der vorherige TextInput‚s onSubmitEditingausgelöst wird.

Versuche dies

  1. Hinzufügen eines Verweises zum zweiten TextInput
    ref={(input) => { this.secondTextInput = input; }}

  2. Binden Sie die Fokusfunktion an das erste onSubmitEditing -Ereignis von TextInput.
    onSubmitEditing={() => { this.secondTextInput.focus(); }}

  3. Denken Sie daran, blurOnSubmit auf false zu setzen, um ein Flackern der Tastatur zu verhindern.
    blurOnSubmit={false}

Wenn alles erledigt ist, sollte es so aussehen.

<TextInput
    placeholder="FirstTextInput"
    returnKeyType="next"
    onSubmitEditing={() => { this.secondTextInput.focus(); }}
    blurOnSubmit={false}
/>

<TextInput
    ref={(input) => { this.secondTextInput = input; }}
    placeholder="secondTextInput"
/>
Langeweile
quelle
53
Erwähnenswert ist, dass dieser onSubmitEditingRückruf nach dem blurEreignis aufgerufen wird . Die Tastatur kann also verrückt werden, wenn sie sich sofort auf das nächste Element konzentriert. Daher kann es hilfreich sein, blurOnSubmit={false}alle Elemente in der Form festzulegen, aber das trueletzte Element beizubehalten, damit die Schaltfläche Fertig die letzte Eingabe verwischen kann.
e1dar
9
Dies funktioniert ab Version 0.36 nicht mehr. Es gibt keine Methode "Fokus" auf die Komponente. Wie sollen wir das jetzt machen?
Mitch
4
@Mitch funktioniert gut auf 0.40.0. Könnte ein Fehler in der Version gewesen sein, die Sie ausgeführt haben.
Vikki
3
Wenn Sie RN 0.49 verwenden, um blurOnSubmit={false}ein Flackern der Tastatur zu verhindern, funktioniert dies nicht mehr. Wer weiß, was los ist?
Nabil London
13
Stellen Sie für alle, die es nicht schaffen, focusArbeit zu leisten , sicher, dass Sie keinen Wrapper für TextInputKomponenten verwenden. Wenn Sie eine Say- CustomTextInputKomponente haben, die umbrochen wird TextInput, müssen Sie TextInputUnschärfe- und Fokusmethoden für diese Komponente implementieren , damit sie wie erwartet funktioniert.
Cihad Turhan
65

Sie können dies ohne Verwendung von Refs tun . Dieser Ansatz wird bevorzugt, da Refs zu fragilem Code führen können . In den React-Dokumenten wird empfohlen, nach Möglichkeit andere Lösungen zu finden:

Wenn Sie nicht mehrere Apps mit React programmiert haben, besteht Ihre erste Neigung normalerweise darin, Refs zu verwenden, um "Dinge geschehen zu lassen" in Ihrer App. Wenn dies der Fall ist, nehmen Sie sich einen Moment Zeit und überlegen Sie kritischer, wo sich der Status in der Komponentenhierarchie befinden sollte. Oft wird klar, dass der richtige Ort, um diesen Zustand zu "besitzen", auf einer höheren Ebene in der Hierarchie liegt. Wenn Sie den Status dort platzieren, wird häufig der Wunsch beseitigt, Refs zu verwenden, um "Dinge geschehen zu lassen". Stattdessen wird der Datenfluss normalerweise Ihr Ziel erreichen.

Stattdessen verwenden wir eine Statusvariable, um das zweite Eingabefeld zu fokussieren.

  1. Fügen Sie eine Statusvariable hinzu, die wir als Requisite an folgende Adresse übergeben DescriptionInput:

    initialState() {
      return {
        focusDescriptionInput: false,
      };
    }
  2. Definieren Sie eine Handler-Methode, die diese Statusvariable auf true setzt:

    handleTitleInputSubmit() {
      this.setState(focusDescriptionInput: true);
    }
  3. Nach dem Absenden / Drücken von Enter / Next am TitleInputrufen wir an handleTitleInputSubmit. Dies wird focusDescriptionInputauf true gesetzt.

    <TextInput 
       style = {styles.titleInput}
       returnKeyType = {"next"}
       autoFocus = {true}
       placeholder = "Title" 
       onSubmitEditing={this.handleTitleInputSubmit}
    />
  4. DescriptionInputDie focusRequisite wird auf unsere focusDescriptionInputZustandsvariable gesetzt. Wenn also focusDescriptionInputÄnderungen (in Schritt 3) DescriptionInputmit neu gerendert werden focus={true}.

    <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 können :)

EDIT: h / t an @LaneRettig, um darauf hinzuweisen, dass Sie den React Native TextInput mit einigen zusätzlichen Requisiten und Methoden umschließen müssen, damit er auf Folgendes reagiert focus:

    // Props:
    static propTypes = { 
        focus: PropTypes.bool,
    } 

    static defaultProps = { 
        focus: false,
    } 

    // Methods:
    focus() {
        this._component.focus(); 
    } 

    componentWillReceiveProps(nextProps) {
        const {focus} = nextProps; 

        focus && this.focus(); 
    }
Stedman Blake
quelle
2
@ LaneRettig Du hast vollkommen recht - danke, dass du darauf hingewiesen hast. Wir verpacken RN TextInput mit einigen zusätzlichen Requisiten und Methoden - siehe unten in der Antwort mit diesen Ergänzungen und lassen Sie mich wissen, wenn Sie weitere Probleme haben!
Stedman Blake
4
Cool. Sie sollten dies als PR an RN senden. Ich bin überrascht, dass dies nicht bereits sofort unterstützt wird.
Lane Rettig
8
Was ist, wenn Sie auf der Tastatur auf Weiter klicken und dann direkt auf die erste Eingabe klicken? Der Fokus geht zurück auf den zweiten Platz, was eine schlechte Erfahrung mit dieser Lösung ist
Piotr
3
Ich mag diese Lösung nicht, insbesondere, weil sie nicht gut für noch etwas längere Formen von 5-6 Elementen skaliert werden kann, bei denen Sie für jedes Element einen booleschen Fokusstatus benötigen und alle entsprechend verwalten.
Davidgoli
9
Interessanterweise heißt es in den Dokumenten auch: "Es gibt einige gute Anwendungsfälle für Refs: Verwalten des Fokus, der Textauswahl oder der Medienwiedergabe ..." In diesem Fall wäre die Verwendung von Refs zum Fokussieren der Texteingabe eine gültige Verwendung des Tools .
Noah Allen
26

Ab React Native 0.36 wird das Aufrufen focus()(wie in mehreren anderen Antworten vorgeschlagen) eines Texteingabeknotens nicht mehr unterstützt. Stattdessen können Sie das TextInputStateModul von React Native verwenden. Ich habe das folgende Hilfsmodul erstellt, um dies zu vereinfachen:

// 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 die focusTextInputFunktion dann für jede "Referenz" von a aufrufen TextInput. Beispielsweise:

...
<TextInput onSubmit={() => focusTextInput(this.refs.inputB)} />
<TextInput ref="inputB" />
...
Mitch
quelle
1
Funktioniert super, aber wenn jemand Redux-Form verwendet, sollte er so etwas tun. <Field ... onSubmitEditing={() => focusTextInput(this._password)} />und ref sollte so sein<Field ... withRef refName={e => this._password = e}/>
tarkanlar
1
Ich musste 'onSubmitEditing' verwenden, damit dies funktioniert, aber trotzdem eine großartige Lösung.
Adam Jakiela
3
Funktioniert hervorragend in 0.42.
Lawrence
1
@tarkanlar können Sie Code-Snippet für die Lösung teilen? Ich kann mich nicht konzentrieren, wenn ich Redux-Form Field verwende, nur TextInput funktioniert, gut
Jasan
2
calling focus() on a text input node isn't supported any more=> kühne Behauptung, Quelle? Das Aufrufen focus()funktioniert gut mit v0.49.5 + TextInputStateist nicht dokumentiert focus()und blur()wird erwähnt: facebook.github.io/react-native/releases/next/docs/…
tanguy_k
21

Ich habe eine kleine Bibliothek erstellt, die dies tut. Es ist keine Codeänderung erforderlich, außer dass Sie Ihre Umbruchansicht ersetzen und TextInput importieren:

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

Hier ausführlich erklärt: https://zach.codes/autofocus-inputs-in-react-native/

zackifizieren
quelle
Hervorragendes Muster, um dieses Ergebnis zu erzielen. Sollte vom Standpunkt der Benutzerfreundlichkeit aus die beste Antwort sein. Anscheinend kann ich meine benutzerdefinierten FormInput (TextInput-Erweiterungen) problemlos bearbeiten, um weiterhin mit Ihren Formulareingaben zu arbeiten. Stört es Sie, wenn ich es Ihrer Antwort hinzufüge, wenn zum Beispiel?
Jack Robson
Sicher! Ich weiß ... Ich habe dies in einem anderen beliebten Beitrag darüber gepostet, bin aber wegen Duplikaten in Schwierigkeiten geraten. Ich versuche nur zu helfen, weil ich weiß, wie nervig dieses Problem ist !!
Zackify
Dies ist großartig, wenn Sie eine Reihe von TextInputs direkt nacheinander haben, aber wenn Sie zwischen ihnen ein Styling hinzufügen möchten, bricht es zusammen. Vielen Dank für den Beitrag.
GenericJam
Fühlen Sie sich frei, den Code anzupassen. Ich bin sicher, Sie könnten einen Weg finden, der Elemente überspringt, die keine Texteingaben sind. Sollte nicht zu schwer sein.
Zackify
1
Dies baut nicht für die Produktion [email protected]
Phil Andrews
17

Ich dachte, ich würde meine Lösung mit einer Funktionskomponente teilen ... ' das ' wird nicht benötigt!

Reagiere 16.12.0 und reagiere Native 0.61.5

Hier ist ein Beispiel meiner Komponente:

import React, { useRef } from 'react'
...


const MyFormComponent = () => {

  const ref_input2 = useRef();
  const ref_input3 = useRef();

  return (
    <>
      <TextInput
        placeholder="Input1"
        autoFocus={true}
        returnKeyType="next"
        onSubmitEditing={() => ref_input2.current.focus()}
      />
      <TextInput
        placeholder="Input2"
        returnKeyType="next"
        onSubmitEditing={() => ref_input3.current.focus()}
        ref={ref_input2}
      />
      <TextInput
        placeholder="Input3"
        ref={ref_input3}
      />
    </>
  )
}

Ich weiß nicht, hoffe das hilft jemandem =)

Eli Johnson
quelle
1
funktioniert nicht. undefined ist kein Objekt, das _this2.ref_input2.current auswertet. Bitte helfen Sie
DEEP ADHIYA
Können Sie ein vollständigeres Beispiel für Ihren Code liefern?
Eli Johnson
2
Möglicherweise ist es besser, useRef in der Funktionskomponente zu verwenden als createRef
hyuk lee
@hyuklee Sie sind in der Tat richtig, Sir, ich habe aktualisiert ... danke für die Heads-up! Prost!
Eli Johnson
Für diejenigen, die gerne über die neuesten React-Updates informiert sind, ist dies DIE ANTWORT.
Yokhen
13

Bei der Verwendung von react-native 0.45.1 sind auch Probleme beim Versuch aufgetreten, den Fokus auf ein Kennwort TextInput zu legen, nachdem die Eingabetaste für einen Benutzernamen TextInput gedrückt wurde.

Nachdem ich die meisten der am besten bewerteten Lösungen hier auf SO ausprobiert hatte, fand ich auf github eine Lösung, die meinen Anforderungen entsprach: 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>
        )
    }
}
kuhr
quelle
Du
rettest
1
Sie haben lediglich umbenannt refin inputRef... Sie könnten Ihre gesamte benutzerdefinierte Komponente löschen und Ihr zweiter Codeblock funktioniert so wie er ist, solange Sie wieder verwendenref
Jason Tolliver
9

Für mich auf RN 0.50.3 ist dies folgendermaßen möglich:

<TextInput 
  autoFocus={true} 
  onSubmitEditing={() => {this.PasswordInputRef._root.focus()}} 
/>

<TextInput ref={input => {this.PasswordInputRef = input}} />

Sie müssen this.PasswordInputRef sehen. _root .focus ()

Wunschmeister
quelle
1
Dies ist "native-base" spezifisch
Developia
8

Wenn Sie zufällig so verwenden tcomb-form-nativewie ich, können Sie dies auch tun. Hier ist der Trick: Anstatt die Requisiten des TextInputdirekt zu setzen, machst du es ü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 hier: https://github.com/gcanti/tcomb-form-native/issues/96 )

Lane Rettig
quelle
Wie rufe ich die Funktion onSubmitEditing auf? Zum Beispiel: Ich möchte die Funktion login () aufrufen, wenn der Benutzer den Returnkey-Typ 'done' des letzten Texteingangs drückt.
Chetan
7

So habe ich es erreicht. Im folgenden Beispiel wurde 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.

Janaka Pushpakumara
quelle
Was ist der Zweck von .current?
Adam Katz
5

Mein Szenario ist <CustomBoladonesTextInput /> , das einen RN <TextInput /> umschließt .

Ich habe dieses Problem wie folgt gelöst:

Mein Formular sieht aus wie:

  <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 die innere ref-Requisite:

   export default class CustomBoladonesTextInput extends React.Component {
      render() {        
         return (< TextInput ref={this.props.refInner} ... />);     
      } 
   }

Und voila. Alles zurück funktioniert wieder. Hoffe das hilft

Rodrigo Tessarollo
quelle
4

Probieren Sie diese Lösung bei GitHub-Problemen von React Native aus.

https://github.com/facebook/react-native/pull/2149#issuecomment-129262565

Sie müssen die Referenz für die TextInput-Komponente verwenden.
Dann müssen Sie eine Funktion erstellen, die für die onSubmitEditing-Requisite aufgerufen wird und den Fokus auf die zweite TextInput-Referenz verschiebt.

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>
        );
    }
});
APAquino
quelle
Bitte geben Sie die entsprechenden Informationen aus dem Link in Ihrer Antwort an.
Wes Foster
Beachten Sie, dass String-Refs möglicherweise veraltet sind, sodass diese Lösung möglicherweise in Zukunft nicht mehr funktioniert: "... Obwohl String-Refs nicht veraltet sind, gelten sie als Legacy und werden wahrscheinlich zu einem späteren Zeitpunkt veraltet sein. Rückruf-Refs sind es bevorzugt." - facebook.github.io/react/docs/more-about-refs.html
Yura
1
Dies funktioniert ab Version 0.36 nicht mehr. Es gibt keine Methode "Fokus" auf die Komponente. Wie sollen wir das jetzt machen? Können Sie die Antwort aktualisieren?
Mitch
@Mitch nicht sicher, ob dies wieder auf 0.39.2 ist, aber das funktioniert jetzt gut.
Eldelshell
4

Mit Callback - Refs statt des Legacy - Zeichenfolge Refs:

<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}
/>
Fagerbua
quelle
1
Funktioniert nicht, da die Fokusmethode aus TextInput entfernt wurde.
Jacob Lauritzen
3
<TextInput 
    keyboardType="email-address"
    placeholder="Email"
    returnKeyType="next"
    ref="email"
    onSubmitEditing={() => this.focusTextInput(this.refs.password)}
    blurOnSubmit={false}
 />
<TextInput
    ref="password"
    placeholder="Password" 
    secureTextEntry={true} />

Und fügen Sie die Methode onSubmitEditing={() => this.focusTextInput(this.refs.password)}wie folgt hinzu:

private focusTextInput(node: any) {
    node.focus();
}
Nisar
quelle
2

Damit die akzeptierte Lösung funktioniert, wenn Sie TextInputsich in einer anderen Komponente befinden, müssen Sie die Referenz refin den übergeordneten Container "einfügen" .

// 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}/>
}
Eldelshell
quelle
1
Hallo @Eldelshell, ich würde gerne das Gleiche erreichen, konnte aber Ihre Stichprobe nicht sortieren. Würde es Ihnen etwas ausmachen, uns einen Hinweis zu geben?
Seeliang
Ich denke, das sollte die richtige Antwort sein. Ich folge dem und es funktioniert.
David Cheung
Sind beide in derselben Datei?
MoralCode
2

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 verwendet, ._rootweil es ein Verweis auf TextInput in ist NativeBase'Library 'Input handelt

und in Ihren Texteingaben wie folgt

<TextInput
         onSubmitEditing={() => {
                          this.focusNextField('two');
                          }}
         returnKeyType="next"
         blurOnSubmit={false}/>


<TextInput      
         ref={input => {
              this.inputs['two'] = input;
                        }}/>
amorenew
quelle
2
<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();
}
Saloni Parikh
quelle
Sehr ordentlicher Ansatz.
Siraj Alam
1
Alte Antwort, aber weiß jemand, ob es möglich ist, auf alle Refs wie in dieser Antwort in einer funktionalen (zustandslosen) Komponente zuzugreifen?
Douglas Schmidt
1

Es gibt eine Möglichkeit, Registerkarten in a zu erfassen TextInput. Es ist hacky, aber besser als nichts .

Definieren Sie einen onChangeTextHandler, der den neuen Eingabewert mit dem alten vergleicht und nach a sucht\t . Wenn eines gefunden wird, erweitern Sie das Feld wie in @boredgames gezeigt

Angenommen, die Variable usernameenthält den Wert für den Benutzernamen undsetUsername löst eine Aktion aus, um ihn im Speicher zu ändern (Komponentenstatus, Redux-Speicher usw.). 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} />
    )
  }
}
Marius
quelle
Dies funktionierte bei mir mit einer physischen Tastatur nicht. Das Ereignis onChangeText wird auf der Registerkarte nicht ausgelöst.
Bufke
0

Hier eine Reagenzlösung für eine Eingabekomponente mit der Eigenschaft: focus.

Das Feld wird fokussiert, solange diese Requisite auf wahr gesetzt ist, und es wird nicht fokussiert, solange dies falsch ist.

Leider muss für diese Komponente ein: ref definiert sein. Ich konnte keinen anderen Weg finden, um .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

Knotschi
quelle
@ Tap - das ist Clojurescript. Reagenz ist eine Bindung an React. Wenn Sie neugierig sind, passt es hervorragend zu React, wenn Sie Lust auf ein Lispeln haben, da Stateful-Updates im Allgemeinen nur mit Dingen wie einem expliziten Aufruf swap!eines atomTyps möglich sind. Gemäß den Dokumenten wird dies für die Bindung an React verwendet: "Jede Komponente, die ein Atom verwendet, wird automatisch neu gerendert, wenn sich ihr Wert ändert." reaent-project.github.io
Del
0

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>
Mohamed Ben Hartouz
quelle