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

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

但在按下键盘上的“next”按钮后,我的react-native应用程序并没有跳转到第二个TextInput字段。我怎样才能做到呢?

谢谢!


当前回答

在React Native的GitHub问题上尝试这个解决方案。

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

你需要为TextInput组件使用ref道具。 然后你需要创建一个函数,该函数在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>
        );
    }
});

其他回答

结合@Eli Johnson的功能组件解决方案和@Rodrigo Tessarollo的CustomTextInput解决方案:

import React, { useRef } from 'react';
import { CustomTextInput } from 'path/to/CustomTextInput';
...


export const MyFormComponent = () => {

  const ref_to_input2 = useRef();

  return (
    <>
      <CustomTextInput
        placeholder="Input 1"
        autoFocus={true}
        returnKeyType="next"
        onSubmitEditing={() => ref_to_input2.current.focus()}
      />
      <CustomTextInput
        placeholder="Input 2"
        returnKeyType="done"
        refInner={ref_to_input2}
        onSubmitEditing={/* Do something! */}
      />
    </>
  )
}

在你的CustomTextInput组件中:

import { TextInput } from "react-native";
export const CustomTextInput = (props) => {
  <TextInput
        ref={props.refInner}
        {...props}
  />
}
<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.ref .password)}如下所示:

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

你不需要裁判也可以做到。这种方法是首选的,因为引用会导致脆弱的代码。React文档建议在可能的情况下寻找其他解决方案:

If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.

相反,我们将使用一个状态变量来聚焦第二个输入字段。

Add a state variable that we'll pass as a prop to the DescriptionInput: initialState() { return { focusDescriptionInput: false, }; } Define a handler method that will set this state variable to true: handleTitleInputSubmit() { this.setState(focusDescriptionInput: true); } Upon submitting / hitting enter / next on the TitleInput, we'll call handleTitleInputSubmit. This will set focusDescriptionInput to true. <TextInput style = {styles.titleInput} returnKeyType = {"next"} autoFocus = {true} placeholder = "Title" onSubmitEditing={this.handleTitleInputSubmit} /> DescriptionInput's focus prop is set to our focusDescriptionInput state variable. So, when focusDescriptionInput changes (in step 3), DescriptionInput will re-render with focus={true}. <TextInput style = {styles.descriptionInput} multiline = {true} maxLength = {200} placeholder = "Description" focus={this.state.focusDescriptionInput} />

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

编辑:h/t @LaneRettig指出,你需要用一些添加的道具和方法来包装React Native TextInput,以获得对焦点的响应:

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

    static defaultProps = { 
        focus: false,
    } 

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

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

        focus && this.focus(); 
    }

我就是这样做到的。下面的例子使用了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}
/>