React Native:如何在按下“下一个”键盘button后select下一个TextInput?

我定义了两个TextInput字段,如下所示:

<TextInput style = {styles.titleInput} returnKeyType = {"next"} autoFocus = {true} placeholder = "Title" /> <TextInput style = {styles.descriptionInput} multiline = {true} maxLength = {200} placeholder = "Description" /> 

但是按下键盘上的“下一步”button后,我的反应本机应用程序不会跳转到第二个TextInput字段。 我怎样才能做到这一点?

谢谢!

将焦点设置在最后一个onSubmitEditing上的下一个文本input上。 试试..

 <TextInput style = {styles.titleInput} returnKeyType = {"next"} autoFocus = {true} placeholder = "Title" onSubmitEditing={(event) => { this.refs.SecondInput.focus(); }} /> <TextInput ref='SecondInput' style = {styles.descriptionInput} multiline = {true} maxLength = {200} placeholder = "Description" /> 

你可以做到这一点, 而不使用裁判 。 这种方法是首选,因为参考可能会导致脆弱的代码 。 React文档build议尽可能find其他解决scheme:

如果您还没有使用React编写多个应用程序,您的第一个倾向通常是尝试在应用程序中使用参考“让事情发生”。 如果是这样的话,花一点时间,仔细想一想组件层次结构中应该拥有哪个状态。 通常情况下,很显然,“拥有”这个国家的适当位置在层级中处于更高的层次。 将状态放在那里通常会消除使用引用来“使事情发生”的愿望 – 相反,数据stream通常会实现您的目标。

相反,我们将使用状态variables来聚焦第二个input字段。

  1. 添加一个状态variables,我们将作为一个道具传递给DescriptionInput

     initialState() { return { focusDescriptionInput: false, }; } 
  2. 定义一个将此状态variables设置为true的处理程序方法:

     handleTitleInputSubmit() { this.setState(focusDescriptionInput: true); } 
  3. 在提交/击中TitleInput上的enter / next TitleInput ,我们将调用handleTitleInputSubmit 。 这将设置focusDescriptionInput为true。

     <TextInput style = {styles.titleInput} returnKeyType = {"next"} autoFocus = {true} placeholder = "Title" onSubmitEditing={this.handleTitleInputSubmit} /> 
  4. DescriptionInputfocus道具被设置为我们的focusDescriptionInput状态variables。 因此,当focusDescriptionInput发生变化时(在步骤3中),将使用focus={true}重新呈现DescriptionInput

     <TextInput style = {styles.descriptionInput} multiline = {true} maxLength = {200} placeholder = "Description" focus={this.state.focusDescriptionInput} /> 

这是避免使用refs的好方法,因为refs会导致更脆弱的代码:)

编辑:h / t to @LaneRettig指出你需要用一些附加的道具和方法来包装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(); } 

从React Native 0.36开始,不再支持在文本input节点上调用focus() (正如其他几个答案中所build议的那样)。 相反,您可以使用React Native中的TextInputState模块。 我创build了以下帮助程序模块以使其更容易:

 // 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) } } 

然后,可以在TextInput任何“ref”上调用focusTextInput函数。 例如:

 ... <TextInput onSubmit={() => focusTextInput(this.refs.inputB)} /> <TextInput ref="inputB" /> ... 

我创build了一个这样的小型库,除了replace包装视图和导入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/

如果你碰巧正在使用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-native 0.45.1我也遇到了一些问题,试图在按下用户名TextInput上的返回键之后将焦点设置为密码TextInput。

在尝试了大部分顶级解决scheme之后,我在github上find了满足我需求的解决scheme: 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> ) } } 

在React Native的GitHub问题上试试这个解决scheme。

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

您需要为TextInput组件使用ref prop。
然后你需要创build一个函数,在onSubmitEditing道具上调用,将焦点移到第二个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> ); } }); 

使用callback引用而不是传统的string引用:

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

有一种方法可以捕获TextInput 选项卡 。 这是hacky,但总比没有好 。

定义一个onChangeText处理程序,将新的input值与旧的进行比较,检查\t 。 如果find一个,按照@boredgames所示前进该字段

假设variablesusername包含username的值, setUsername调度一个动作来改变它在商店(组件状态,REDEX存储等),做这样的事情:

 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} /> ) } } 

对于可接受的解决scheme,如果你的TextInput在另一个组件内,你需要从ref “popup”引用到父容器。

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

在你的组件中:

 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(); } 

注意:我使用._root因为它是NativeBase'Library'Input中 TextInput的引用

并在你的文字input这样

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

这里是用于具有聚焦属性的input组件的试剂溶液。

只要这个道具被设置为真,只要这个道理是错误的,这个领域就会被聚焦。

不幸的是,这个组件需要有一个:ref定义,我找不到其他的方式来调用.focus()。 我对build议感到高兴。

 (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