次のように2つのTextInputフィールドを定義しました。
<TextInput
style = {styles.titleInput}
returnKeyType = {"next"}
autoFocus = {true}
placeholder = "Title" />
<TextInput
style = {styles.descriptionInput}
multiline = {true}
maxLength = {200}
placeholder = "Description" />
しかし、私のキーボードの「次へ」ボタンを押した後、私の反応ネイティブアプリは2番目のTextInputフィールドにジャンプしません。どうすればそれを達成できますか?
ありがとうございます。
前のTextInput
のTextInput
がトリガーされたときに、2番目のonSubmitEditing
フォーカスを設定します。
これを試して
secondへのRefの追加TextInputref={(input) => { this.secondTextInput = input; }}
フォーカス関数を最初のTextInputのonSubmitEditingイベントにバインドします。onSubmitEditing={() => { this.secondTextInput.focus(); }}
キーボードのちらつきを防ぐために、blurOnSubmitをfalseに設定することを忘れないでください。blurOnSubmit={false}
すべて完了したら、これは次のようになります。
<TextInput
placeholder = "FirstTextInput"
returnKeyType = { "next" }
onSubmitEditing={() => { this.secondTextInput.focus(); }}
blurOnSubmit={false}
/>
<TextInput
ref={(input) => { this.secondTextInput = input; }}
placeholder = "secondTextInput"
/>
あなたはこれをすることができます 参照を使用せずに 。参照は 壊れやすいコード につながる可能性があるので、このアプローチが好ましいです。 Reactのドキュメント は、可能な限り他の解決策を見つけることをお勧めします。
Reactを使っていくつかのアプリをプログラムしていないのであれば、あなたの最初の傾向は通常、refsを使ってアプリ内で「問題を起こす」ことを試みることです。その場合は、少し時間をかけて、コンポーネント階層のどこで状態を所有するのかについて、もっと批判的に考えてください。多くの場合、その状態を「所有する」ための適切な場所が階層の上位レベルにあることが明らかになります。状態をそこに置くことは、しばしば「物事を起こさせる」ために参照を使用するという欲求を排除します - 代わりに、データフローは通常あなたの目標を達成するでしょう。
代わりに、状態変数を使用して2番目の入力フィールドにフォーカスします。
支柱としてDescriptionInput
に渡す状態変数を追加します。
initialState() {
return {
focusDescriptionInput: false,
};
}
この状態変数をtrueに設定するハンドラメソッドを定義します。
handleTitleInputSubmit() {
this.setState(focusDescriptionInput: true);
}
TitleInput
にenter/nextを送信する/押すと、handleTitleInputSubmit
が呼び出されます。これはfocusDescriptionInput
をtrueに設定します。
<TextInput
style = {styles.titleInput}
returnKeyType = {"next"}
autoFocus = {true}
placeholder = "Title"
onSubmitEditing={this.handleTitleInputSubmit}
/>
DescriptionInput
のfocus
propは、focusDescriptionInput
状態変数に設定されています。そのため、(ステップ3で)focusDescriptionInput
が変更されると、DescriptionInput
はfocus={true}
で再レンダリングされます。
<TextInput
style = {styles.descriptionInput}
multiline = {true}
maxLength = {200}
placeholder = "Description"
focus={this.state.focusDescriptionInput}
/>
Refはより脆弱なコードにつながる可能性があるので、これはrefの使用を避けるための良い方法です:)
編集:focus
に応答させるためにReact Native TextInputをいくつかの追加された小道具とメソッドでラップする必要があることを指摘してくれた@LaneRettigのh/t:
// Props:
static propTypes = {
focus: PropTypes.bool,
}
static defaultProps = {
focus: false,
}
// Methods:
focus() {
this._component.focus();
}
componentWillReceiveProps(nextProps) {
const {focus} = nextProps;
focus && this.focus();
}
React Native 0.36以降、テキスト入力ノードでfocus()
を呼び出すこと(他のいくつかの回答で示唆されているように)は、もうサポートされません。代わりに、React NativeのTextInputState
モジュールを使うことができます。これを簡単にするために、次のようなヘルパーモジュールを作成しました。
// 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)
}
}
その後、focusTextInput
の任意の "ref"に対してTextInput
関数を呼び出すことができます。例えば:
...
<TextInput onSubmit={() => focusTextInput(this.refs.inputB)} />
<TextInput ref="inputB" />
...
これを行う小さなライブラリを作成しました。ラッピングビューを置き換えてTextInputをインポートする以外はコードを変更する必要はありません。
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
ここで詳しく説明されています: https://zach.codes/autofocus-inputs-in-react-native/
React-native 0.45.1の使用ユーザー名TextInputでリターンキーを押した後、パスワードTextInputにフォーカスを設定しようとしたときにも問題が発生しました。
SOでトップクラスの解決策のほとんどを試した後、私は自分のニーズを満たすgithub上の解決策を見つけました: https://github.com/shoutem/ui/ issues/44#issuecomment-290724642
まとめると、
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)}
/>
);
}
}
それから私はこれを次のように使います。
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>
)
}
}
私はRN 0.50.3でこれが可能です
<TextInput
autoFocus={true}
onSubmitEditing={() => {this.PasswordInputRef._root.focus()}}
/>
<TextInput ref={input => {this.PasswordInputRef = input}} />
This.PasswordInputRef。_ root。focus()が表示されます。
偶然 tcomb-form-native
を使っているのなら、これもできます。これがトリックです:TextInput
の小道具を直接設定する代わりに、あなたはoptions
を通してそれを行います。フォームのフィールドを次のように参照することができます。
this.refs.form.getComponent('password').refs.input.focus()
そのため、最終的な製品は次のようになります。
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>
);
},
});
(このアイデアをここに投稿してくれたことで、remcoankerにクレジットしてください: https://github.com/gcanti/tcomb-form-native/issues/96 )
これが私が達成した方法です。そして以下の例はReact 16.3で導入されたReact.createRef()APIを使用しています。
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>
);
}
}
これはあなたに役立つと思います。
従来の 文字列参照の代わりにコールバック参照を使用する:
<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}
/>
私のシナリオは、<CustomBoladonesTextInput />で、RNをラップ<TextInput />です。
私は以下のようにこの問題を解決しました:
私の形は次のようになります。
<CustomBoladonesTextInput
onSubmitEditing={() => this.customInput2.refs.innerTextInput2.focus()}
returnKeyType="next"
... />
<CustomBoladonesTextInput
ref={ref => this.customInput2 = ref}
refInner="innerTextInput2"
... />
CustomBoladonesTextInputのコンポーネント定義では、次のようにrefFieldを内部のrefプロップに渡します。
export default class CustomBoladonesTextInput extends React.Component {
render() {
return (< TextInput ref={this.props.refInner} ... />);
}
}
そして、やあ。戻ってきたすべてが再び動作します。お役に立てれば
React NativeのGitHub問題でこの解決策を試してください。
https://github.com/facebook/react-native/pull/2149#issuecomment-129262565
TextInputコンポーネントにはref propを使用する必要があります。
次に、2番目のTextInput参照にフォーカスを移すonSubmitEditing propで呼び出される関数を作成する必要があります。
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>
);
}
});
あなたのTextInput
が別のコンポーネントの中にある場合に受け入れられる解決策が機能するためには、ref
から親コンテナへの参照を "ポップ"する必要があります。
// 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}/>
}
<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%', }} />
メソッドを追加します
focusNextField(nextField) {
this.refs[nextField].focus();
}
TextInput
の中でタブをキャプチャする方法があります。ハッキーですが、 何もない よりも優れています。
\t
をチェックしながら、新しい入力値と古い入力値を比較するonChangeText
ハンドラを定義します。見つかった場合は、@ boredgamesのようにフィールドを進めます。
変数username
がusernameの値を含み、setUsername
がストア内でそれを変更するアクション(コンポーネント状態、reduxストアなど)をディスパッチすると仮定すると、次のようにします。
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} />
)
}
}
あなたのコンポーネントで:
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();
}
注: NativeBase'Library 'Input のTextInputへの参照であるため、私は._root
を使用しました。
そしてあなたのテキスト入力でこのように
<TextInput
onSubmitEditing={() => {
this.focusNextField('two');
}}
returnKeyType="next"
blurOnSubmit={false}/>
<TextInput
ref={input => {
this.inputs['two'] = input;
}}/>
NativeBaseをUIコンポーネントとして使用している場合は、このサンプルを使用できます。
<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>```
ここでは、:focusプロパティを持つ入力コンポーネント用の試薬溶液です。
この小道具がtrueに設定されている限りこの分野に焦点が当てられ、falseである限り焦点は当てられません。
残念ながら、このコンポーネントは:refを定義する必要があります。私はそれに.focus()を呼び出すための他の方法を見つけることができませんでした。私は提案に満足しています。
(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