我定义了两个TextInput字段,如下所示:
<TextInput
style = {styles.titleInput}
returnKeyType = {"next"}
autoFocus = {true}
placeholder = "Title" />
<TextInput
style = {styles.descriptionInput}
multiline = {true}
maxLength = {200}
placeholder = "Description" />
但在按下&#34; next&#34;我的键盘上的按钮,我的本机应用程序没有跳转到第二个TextInput字段。我怎样才能做到这一点?
谢谢!
答案 0 :(得分:217)
在触发上一个TextInput
的{{1}}时设置第二个TextInput
焦点。
试试这个
将参考添加到第二个TextInput
onSubmitEditing
将焦点功能绑定到第一个TextInput 的onSubmitEditing事件。
ref={(input) => { this.secondTextInput = input; }}
请记住将blurOnSubmit设置为false,以防止键盘闪烁
onSubmitEditing={() => { this.secondTextInput.focus(); }}
完成后,它应该是这样的。
blurOnSubmit={false}
答案 1 :(得分:47)
您可以执行此操作,而不使用参考。这种方法是首选,因为refs可能导致脆弱的代码。 React docs建议尽可能找到其他解决方案:
如果您还没有使用React编写多个应用程序,那么您的第一个应用程序 倾向通常是尝试使用refs来制造东西 发生&#34;在你的应用程序中如果是这种情况,请花一点时间思考更多 批判性的关于组件中应该拥有哪个州 层次结构。通常情况下,很明显,适当的地方是拥有&#34;那 state在层次结构中处于更高级别。把国家放在那里 通常会消除任何使用refs以使事情发生的愿望。 - 相反,数据流通常会实现您的目标。
相反,我们将使用状态变量来聚焦第二个输入字段。
添加一个我们将作为道具传递给DescriptionInput
的状态变量:
initialState() {
return {
focusDescriptionInput: false,
};
}
定义一个将此状态变量设置为true的处理程序方法:
handleTitleInputSubmit() {
this.setState(focusDescriptionInput: true);
}
在TitleInput
上提交/点击进入/下一步后,我们会致电handleTitleInputSubmit
。这会将focusDescriptionInput
设置为true。
<TextInput
style = {styles.titleInput}
returnKeyType = {"next"}
autoFocus = {true}
placeholder = "Title"
onSubmitEditing={this.handleTitleInputSubmit}
/>
DescriptionInput
&#39; focus
道具设置为我们的focusDescriptionInput
状态变量。因此,当focusDescriptionInput
更改时(在步骤3中),DescriptionInput
将使用focus={true}
重新呈现。
<TextInput
style = {styles.descriptionInput}
multiline = {true}
maxLength = {200}
placeholder = "Description"
focus={this.state.focusDescriptionInput}
/>
这是一种避免使用引用的好方法,因为引用会导致更脆弱的代码:)
编辑:h / t到@LaneRettig指出你需要用一些添加的道具&amp;来包装React Native TextInput。让它回应focus
的方法:
// Props:
static propTypes = {
focus: PropTypes.bool,
}
static defaultProps = {
focus: false,
}
// Methods:
focus() {
this._component.focus();
}
componentWillReceiveProps(nextProps) {
const {focus} = nextProps;
focus && this.focus();
}
答案 2 :(得分:25)
从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)
}
}
然后,您可以在任何&#34; ref&#34;上调用focusTextInput
函数。一个TextInput
。例如:
...
<TextInput onSubmit={() => focusTextInput(this.refs.inputB)} />
<TextInput ref="inputB" />
...
答案 3 :(得分:18)
我创建了一个小型库来执行此操作,除了替换包装视图和导入TextInput之外,无需更改代码:
import { Form, TextInput } from 'react-native-autofocus'
export default () => (
<Form>
<TextInput placeholder="test" />
<TextInput placeholder="test 2" />
</Form>
)
答案 4 :(得分:11)
使用react-native 0.45.1我在按用户名TextInput上的返回键后尝试将焦点设置为密码TextInput时也遇到了问题。
在这里尝试了大多数评价最高的解决方案后,我在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>
)
}
}
答案 5 :(得分:8)
对于RN 0.50.3,我可以这样做:
<TextInput
autoFocus={true}
onSubmitEditing={() => {this.PasswordInputRef._root.focus()}}
/>
<TextInput ref={input => {this.PasswordInputRef = input}} />
你必须看到这个.PasswordInputRef。 _root .focus()
答案 6 :(得分:7)
如果您正好像我一样使用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>
);
},
});
所以最终产品看起来像这样:
mySqlCommand.CommandText = string.Format("INSERT INTO Users (`Full Name`, Birthday, Sex, City, Region, `Zip Code`, Country, `Phone Number`, `Email Address`, `Ticket Number`) VALUES (@Full_Name, @Birthday, @Sex, @City, @Region, @Zip_Code, @Country, @Phone_Number, @Email_Address, @Ticket_Number);");
(感谢remcoanker在此发布这个想法:https://github.com/gcanti/tcomb-form-native/issues/96)
答案 7 :(得分:5)
将@Eli Johnson 的功能组件解决方案与@Rodrigo Tessarollo 的 CustomTextInput 解决方案相结合:
import React, { useRef } from 'react'
...
const MyFormComponent = () => {
const ref_input2 = useRef();
return (
<>
<TextInput
placeholder="Input1"
autoFocus={true}
returnKeyType="next"
onSubmitEditing={() => ref_input2.current.focus()}
/>
<TextInput
placeholder="Input2"
returnKeyType="done"
refInner={ref_input2}
onSubmitEditing={/* Do something! */}
/>
</>
)
}
在您的 CustomTextInput 组件中:
export function CustomTextInput(props) {
<Input
ref={props.refInner}
{...props}
/>
}
答案 8 :(得分:5)
这就是我实现它的方式。下面的示例使用了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>
);
}
}
我认为这会对您有所帮助。
答案 9 :(得分:4)
使用回调引用而不是legacy字符串引用:
<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}
/>
答案 10 :(得分:3)
我的方案是&lt; CustomBoladonesTextInput /&gt; 包裹RN &lt; TextInput /&gt; 。
我解决了这个问题如下:
我的表单如下:
<CustomBoladonesTextInput
onSubmitEditing={() => this.customInput2.refs.innerTextInput2.focus()}
returnKeyType="next"
... />
<CustomBoladonesTextInput
ref={ref => this.customInput2 = ref}
refInner="innerTextInput2"
... />
在CustomBoladonesTextInput&#39的组件定义中,我将refField传递给内部ref prop,如下所示:
export default class CustomBoladonesTextInput extends React.Component {
render() {
return (< TextInput ref={this.props.refInner} ... />);
}
}
瞧。一切都恢复正常。 希望这有帮助
答案 11 :(得分:3)
在React Native的GitHub问题上尝试此解决方案。
https://github.com/facebook/react-native/pull/2149#issuecomment-129262565
您需要使用TextInput组件的ref prop 然后你需要创建一个在onSubmitEditing prop上调用的函数,该函数将焦点移动到第二个TextInput引用。
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>
);
}
});
答案 12 :(得分:2)
如果您的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}/>
}
答案 13 :(得分: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%', }} />
并添加方法
focusNextField(nextField) {
this.refs[nextField].focus();
}
答案 14 :(得分:1)
:
*
注意:我使用了"//*[name()='use' and @*='#aaa']"
,因为它是NativeBase'Library' Input
并在您的文字输入中
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();
}
答案 15 :(得分:1)
有一种方法可以捕获TextInput
中的标签。这很hacky,但比nothing好。
定义一个onChangeText
处理程序,用于将新输入值与旧输入值进行比较,检查\t
。如果找到一个,请按@boredgames
假设变量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} />
)
}
}
答案 16 :(得分:1)
真的很讨厌RN没有某种Tabindex系统。
一个功能组件,对于我的用例,我有一个用于输入的字符串ID数组,这些ID进行迭代并显示每个输入的文本。以下代码将自动使用户跳过所有代码,停止键盘在各字段之间消失/重新出现并在末尾将其关闭,并在键盘上显示相应的“操作”按钮。
打字稿,本机基础。
const stringFieldIDs = [
'q1', 'q2', 'q3'
];
export default () => {
const stringFieldRefs = stringFieldIDs.map(() => useRef < any > ());
const basicStringField = (id: string, ind: number) => {
const posInd = stringFieldIDs.indexOf(id);
const isLast = posInd === stringFieldIDs.length - 1;
return ( <
Input blurOnSubmit = {
isLast
}
ref = {
stringFieldRefs[posInd]
}
returnKeyType = {
isLast ? 'done' : 'next'
}
onSubmitEditing = {
isLast ?
undefined :
() => stringFieldRefs[posInd + 1].current._root.focus()
}
/>
);
};
return stringFieldIDs.map(basicStringField);
};
答案 17 :(得分:1)
import React, { useState, useEffect, useRef, } from 'react';
const OTP = (props) => {
const OTP = [];
const ref_input = [];
ref_input[0] = useRef();
ref_input[1] = useRef();
ref_input[2] = useRef();
ref_input[3] = useRef();
const focusNext = (text, index) => {
if (index < ref_input.length - 1 && text) {
ref_input[index + 1].current.focus();
}
if (index == ref_input.length - 1) {
ref_input[index].current.blur();
}
OTP[index] = text;
}
const focusPrev = (key, index) => {
if (key === "Backspace" && index !== 0) {
ref_input[index - 1].current.focus();
}
}
return (
<SafeAreaView>
<View>
<ScrollView contentInsetAdjustmentBehavior="automatic" showsVerticalScrollIndicator={false}>
<View style={loginScreenStyle.titleWrap}>
<Title style={loginScreenStyle.titleHeading}>Verify OTP</Title>
<Subheading style={loginScreenStyle.subTitle}>Enter the 4 digit code sent to your mobile number</Subheading>
</View>
<View style={loginScreenStyle.inputContainer}>
<TextInput
mode="flat"
selectionColor={Colors.primaryColor}
underlineColorAndroid="transparent"
textAlign='center'
maxLength={1}
keyboardType='numeric'
style={formScreenStyle.otpInputStyle}
autoFocus={true}
returnKeyType="next"
ref={ref_input[0]}
onChangeText={text => focusNext(text, 0)}
onKeyPress={e => focusPrev(e.nativeEvent.key, 0)}
/>
<TextInput
mode="flat"
selectionColor={Colors.primaryColor}
underlineColorAndroid="transparent"
textAlign='center'
maxLength={1}
keyboardType='numeric'
style={formScreenStyle.otpInputStyle}
ref={ref_input[1]}
onChangeText={text => focusNext(text, 1)}
onKeyPress={e => focusPrev(e.nativeEvent.key, 1)}
/>
<TextInput
mode="flat"
selectionColor={Colors.primaryColor}
underlineColorAndroid="transparent"
textAlign='center'
maxLength={1}
keyboardType='numeric'
style={formScreenStyle.otpInputStyle}
ref={ref_input[2]}
onChangeText={text => focusNext(text, 2)}
onKeyPress={e => focusPrev(e.nativeEvent.key, 2)}
/>
<TextInput
mode="flat"
selectionColor={Colors.primaryColor}
underlineColorAndroid="transparent"
textAlign='center'
maxLength={1}
keyboardType='numeric'
style={formScreenStyle.otpInputStyle}
ref={ref_input[3]}
onChangeText={text => focusNext(text, 3)}
onKeyPress={e => focusPrev(e.nativeEvent.key, 3)}
/>
</View>
</ScrollView>
</View>
</SafeAreaView >
)
}
export default OTP;
答案 18 :(得分:1)
这是 reactjs 电话代码输入的实现方法
import React, { useState, useRef } from 'react';
function Header(props) {
const [state , setState] = useState({
phone_number:"",
code_one:'',
code_two:'',
code_three:'',
code_four:'',
submitted:false,
})
const codeOneInput = useRef(null);
const codeTwoInput = useRef(null);
const codeThreeInput = useRef(null);
const codeFourInput = useRef(null);
const handleCodeChange = (e) => {
const {id , value} = e.target
if(value.length < 2){
setState(prevState => ({
...prevState,
[id] : value
}))
if(id=='code_one' && value.length >0){
codeTwoInput.current.focus();
}
if(id=='code_two' && value.length >0){
codeThreeInput.current.focus();
}
if(id=='code_three' && value.length >0){
codeFourInput.current.focus();
}
}
}
const sendCodeToServer = () => {
setState(prevState => ({
...prevState,
submitted : true,
}))
let codeEnteredByUser = state.code_one + state.code_two + state.code_three + state.code_four
axios.post(API_BASE_URL, {code:codeEnteredByUser})
.then(function (response) {
console.log(response)
})
}
return(
<>
<div className="are">
<div className="POP-INN-INPUT">
<input type="text" id="code_one" ref={codeOneInput} value={state.code_one} onChange={handleCodeChange} autoFocus/>
<input type="text" id="code_two" ref={codeTwoInput} value={state.code_two} onChange={handleCodeChange}/>
<input type="text" id="code_three" ref={codeThreeInput} value={state.code_three} onChange={handleCodeChange}/>
<input type="text" id="code_four" ref={codeFourInput} value={state.code_four} onChange={handleCodeChange}/>
</div>
<button disabled={state.submitted} onClick={sendCodeToServer}>
</div>
</>
)
}
export default
答案 19 :(得分:0)
此处为输入组件的试剂溶液,具有:focus属性。
只要此道具设置为true,该场将被聚焦,只要这是假的,就不会有焦点。
不幸的是这个组件需要有一个: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
答案 20 :(得分:0)
如果您将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>```
答案 21 :(得分:0)
<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} />
并为onSubmitEditing={() => this.focusTextInput(this.refs.password)}
添加方法,如下所示:
private focusTextInput(node: any) {
node.focus();
}
答案 22 :(得分:-2)
在自定义组件中添加一个方法,该方法将返回对TextInput的引用。 获取对您的自定义组件的引用,然后在该引用上调用方法。
getInnerRef = () => this.ref;
render() {
return (
<View>
<TextInput
{...this.props}
ref={(r) => this.ref = r}
/>
</View>
)
}
render() {
return (
<View>
<CustomTextInput
onSubmitEditing={() => this.refInput.getInnerRef().focus()}
/>
<CustomTextInput
{...this.props}
ref={(r) => this.refInput = r}
/>
</View>
)
}
最初由 basbase here回答。