我正在try 创建一个密码保护的屏幕.屏幕将使用4个数字输入作为密码.

我这样做的方式是创建一个TextInput组件,并在主屏幕中调用它4次.

我遇到的问题是,当我输入上一个TextInput的值时,TextInputs不会关注下一个.

我对所有PasscodeTextInput组件使用refs(我被告知这是一个遗留方法,但我不知道其他方法,唉).

Tried this method(without creating my own component), no luck too.

Image

index.ios.js

import React, { Component } from 'react';
import { AppRegistry, TextInput, View, Text } from 'react-native';
import { PasscodeTextInput } from './common';

export default class ProgressBar extends Component {
  render() {
    const { centerEverything, container, passcodeContainer,  textInputStyle} = styles;
    return (
      <View style={[centerEverything, container]}>
        <View style={[passcodeContainer]}>
          <PasscodeTextInput
            autoFocus={true}
            ref="passcode1"
            onSubmitEditing={(event) => { this.refs.passcode2.focus() }} />
          <PasscodeTextInput
            ref="passcode2"
            onSubmitEditing={(event) => { this.refs.passcode3.focus() }} />
          <PasscodeTextInput
            ref="passcode3"
            onSubmitEditing={(event) => { this.refs.passcode4.focus() }}/>
          <PasscodeTextInput
            ref="passcode4" />
        </View>
      </View>
    );
  }
}

const styles = {
  centerEverything: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  container: {
    flex: 1,
    backgroundColor: '#E7DDD3',
  },
  passcodeContainer: {
    flexDirection: 'row',
  },
}

AppRegistry.registerComponent('ProgressBar', () => ProgressBar);

PasscodeTextInput.js

import React from 'react';
import {
  View,
  Text,
  TextInput,
  Dimensions
} from 'react-native';

const deviceWidth = require('Dimensions').get('window').width;
const deviceHeight = require('Dimensions').get('window').height;

const PasscodeTextInput = ({ ref, autoFocus, onSubmitEditing, onChangeText, value}) => {

  const { inputStyle, underlineStyle } = styles;

  return(
    <View>
      <TextInput
        ref={ref}
        autoFocus={autoFocus}
        onSubmitEditing={onSubmitEditing}
        style={[inputStyle]}
        maxLength={1}
        keyboardType="numeric"
        placeholderTextColor="#212121"
        secureTextEntry={true}
        onChangeText={onChangeText}
        value={value}
      />
      <View style={underlineStyle} />
    </View>
  );
}

const styles = {
  inputStyle: {
    height: 80,
    width: 60,
    fontSize: 50,
    color: '#212121',
    fontSize: 40,
    padding: 18,
    margin: 10,
    marginBottom: 0
  },
  underlineStyle: {
    width: 60,
    height: 4,
    backgroundColor: '#202020',
    marginLeft: 10
  }
}

export { PasscodeTextInput };

Update 1

index.ios.js

import React, { Component } from 'react';
import { AppRegistry, TextInput, View, Text } from 'react-native';
import { PasscodeTextInput } from './common';

export default class ProgressBar extends Component {

  constructor() {
    super()
    this.state = {
      autoFocus1: true,
      autoFocus2: false,
      autoFocus3: false,
      autoFocus4: false,
    }
  }

  onTextChanged(t) { //callback for immediate state change
    if (t == 2) { this.setState({ autoFocus1: false, autoFocus2: true }, () => { console.log(this.state) }) }
    if (t == 3) { this.setState({ autoFocus2: false, autoFocus3: true }, () => { console.log(this.state) }) }
    if (t == 4) { this.setState({ autoFocus3: false, autoFocus4: true }, () => { console.log(this.state) }) }
  }

  render() {
    const { centerEverything, container, passcodeContainer, testShit, textInputStyle } = styles;
    return (
      <View style={[centerEverything, container]}>
        <View style={[passcodeContainer]}>
          <PasscodeTextInput
            autoFocus={this.state.autoFocus1}
            onChangeText={() => this.onTextChanged(2)} />
          <PasscodeTextInput
            autoFocus={this.state.autoFocus2}
            onChangeText={() => this.onTextChanged(3)} />
          <PasscodeTextInput
            autoFocus={this.state.autoFocus3}
            onChangeText={() => this.onTextChanged(4)} />
          <PasscodeTextInput
            autoFocus={this.state.autoFocus4} />
        </View>
      </View>
    );
  }
}

const styles = {
  centerEverything: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  container: {
    flex: 1,
    backgroundColor: '#E7DDD3',
  },
  passcodeContainer: {
    flexDirection: 'row',
  },
}

AppRegistry.registerComponent('ProgressBar', () => ProgressBar);

推荐答案

不能用这种方式将ref转发到<TextInput>,因为refspecial props中的一个.因此,拨打this.refs.passcode2将返回<PasscodeTextInput>.

try 更改以下内容,从<TextInput>中获得ref.

PasscodeTextInput.js

const PasscodeTextInput = ({ inputRef, ... }) => {

  ...

  return (
    <View>
      <TextInput
        ref={(r) => { inputRef && inputRef(r) }}
        ...
      />
    </View>
    ...
  );
}

然后,将<PasscodeTextInput>中的inputRef分配给一个变量,并使用focus()切换焦点(从RN 0.41.2开始,它并没有被弃用).

index.ios.js

return (
  <PasscodeTextInput
    autoFocus={true}
    onChangeText={(event) => { event && this.passcode2.focus() }} />

  <PasscodeTextInput
    inputRef={(r) => { this.passcode2 = r }}
    onChangeText={(event) => { event && this.passcode3.focus() }} />

  <PasscodeTextInput
    inputRef={(r) => { this.passcode3 = r }}
    onChangeText={(event) => { event && this.passcode4.focus() }} />

  <PasscodeTextInput
    inputRef={(r) => { this.passcode4 = r }} />
);

注意:当试图清除旧密码并输入新密码时,会切换焦点.

React-native相关问答推荐

没有给出相同价值观的时刻

在原生react 中更改图像源URI时闪烁

单击时更改ToucheableOpacity colored颜色 不起作用

单击react 本机时如何从同一屏幕更改内容

防止 React Native 在上下文值更改时重新安装组件

Error: Invariant Violation: Touchable child must either be native or forward setNativeProps to a native component stack

在 React Native 中计算两个 lat+lng 坐标之间的距离?

如何在 React Native 的 Modal 组件上禁用Swipe down to close?

在react native 中出现Cannot read property 'pick算法rithm' of null错误

如何在 ubuntu 上安装 facebook watchman?

如何使 React Native Animated.View 可点击?

React Native require(image) 返回数字

区别需要MainQueueSetup 和dispatch_get_main_queue?

在 FlatList 上使用 React Native 搜索过滤器

在 React Native 中使用小数

仅链接字体的方法

我们可以在 react webapp 和 react native 应用程序之间共享代码吗,并且可以在 react-native 生产环境中使用

为react-native TextInput 设置边框

Expo在使用Windows 10的android模拟器上运行

React Native 多行TextInput,文本居中