Skip to content

TextInput(输入组件)

React Native 核心基础

在 React Native 中,TextInput 是用于接收用户输入的核心组件。它相当于 web 开发中的 inputtextarea 元素,但具有更多的移动设备特定功能。

1. 什么是 TextInput 组件?

TextInput 组件是 React Native 中用于接收用户文本输入的基本组件。它支持多种输入类型、样式和事件处理。

主要功能

  • 文本输入:接收用户输入的文本
  • 输入类型:支持不同类型的输入,如普通文本、密码、数字等
  • 输入验证:支持输入验证和错误提示
  • 自动完成:支持自动完成和建议
  • 键盘处理:支持不同类型的键盘和键盘事件

2. 基本用法

简单使用

jsx
import { View, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function TextInputExample() {
  const [text, setText] = useState('');

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        value={text}
        onChangeText={setText}
        placeholder="Enter text here"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
  },
});

密码输入

jsx
import { View, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function PasswordInput() {
  const [password, setPassword] = useState('');

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        value={password}
        onChangeText={setPassword}
        placeholder="Enter password"
        secureTextEntry
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
  },
});

多行文本输入

jsx
import { View, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function MultilineInput() {
  const [text, setText] = useState('');

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        value={text}
        onChangeText={setText}
        placeholder="Enter multiple lines of text"
        multiline
        numberOfLines={4}
        textAlignVertical="top"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  input: {
    height: 120,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    paddingTop: 10,
  },
});

3. 常用属性

核心属性

属性描述示例
value输入框的值value={text}
onChangeText文本变化回调onChangeText={setText}
placeholder占位文本placeholder="Enter text"
placeholderTextColor占位文本颜色placeholderTextColor="#999"
secureTextEntry是否为密码输入secureTextEntry={true}
multiline是否允许多行输入multiline={true}
numberOfLines显示的行数numberOfLines={4}
keyboardType键盘类型keyboardType="email-address"
autoCapitalize自动大写autoCapitalize="sentences"
autoCorrect自动纠正autoCorrect={false}
maxLength最大输入长度maxLength={50}
editable是否可编辑editable={true}
style样式对象style={styles.input}

键盘类型

类型描述
default默认键盘
email-address电子邮件键盘
numeric数字键盘
phone-pad电话键盘
number-pad数字键盘(只有数字)
decimal-pad带小数点的数字键盘
urlURL 键盘
search搜索键盘

事件属性

属性描述示例
onFocus获得焦点事件onFocus={() => console.log('Input focused')}
onBlur失去焦点事件onBlur={() => console.log('Input blurred')}
onSubmitEditing提交编辑事件onSubmitEditing={() => console.log('Submit')}
onKeyPress按键事件onKeyPress={(e) => console.log('Key pressed:', e.nativeEvent.key)}
onEndEditing结束编辑事件onEndEditing={() => console.log('Editing ended')}

4. 高级用法

带标签的输入框

jsx
import { View, Text, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function LabeledInput() {
  const [name, setName] = useState('');

  return (
    <View style={styles.container}>
      <Text style={styles.label}>Name</Text>
      <TextInput
        style={styles.input}
        value={name}
        onChangeText={setName}
        placeholder="Enter your name"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  label: {
    fontSize: 16,
    marginBottom: 8,
  },
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
  },
});

输入验证

jsx
import { View, Text, TextInput, StyleSheet, TouchableOpacity } from 'react-native';
import { useState } from 'react';

export default function ValidatedInput() {
  const [email, setEmail] = useState('');
  const [error, setError] = useState('');

  const validateEmail = () => {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      setError('Please enter a valid email');
    } else {
      setError('');
      console.log('Email is valid:', email);
    }
  };

  return (
    <View style={styles.container}>
      <TextInput
        style={[styles.input, error ? styles.errorInput : null]}
        value={email}
        onChangeText={setEmail}
        placeholder="Enter your email"
        keyboardType="email-address"
        autoCapitalize="none"
      />
      {error ? <Text style={styles.errorText}>{error}</Text> : null}
      <TouchableOpacity style={styles.button} onPress={validateEmail}>
        <Text style={styles.buttonText}>Validate</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    marginBottom: 8,
  },
  errorInput: {
    borderColor: 'red',
  },
  errorText: {
    color: 'red',
    fontSize: 14,
    marginBottom: 16,
  },
  button: {
    backgroundColor: '#007AFF',
    padding: 10,
    alignItems: 'center',
  },
  buttonText: {
    color: 'white',
    fontSize: 16,
  },
});

自定义输入框

jsx
import { View, TextInput, StyleSheet, TouchableOpacity } from 'react-native';
import { useState } from 'react';

export default function CustomInput() {
  const [text, setText] = useState('');
  const [isFocused, setIsFocused] = useState(false);

  const clearText = () => {
    setText('');
  };

  return (
    <View style={[styles.container, isFocused && styles.containerFocused]}>
      <TextInput
        style={styles.input}
        value={text}
        onChangeText={setText}
        placeholder="Enter text"
        onFocus={() => setIsFocused(true)}
        onBlur={() => setIsFocused(false)}
      />
      {text.length > 0 && (
        <TouchableOpacity onPress={clearText} style={styles.clearButton}>
          <Text style={styles.clearButtonText}>✕</Text>
        </TouchableOpacity>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 8,
    paddingHorizontal: 10,
    margin: 20,
  },
  containerFocused: {
    borderColor: '#007AFF',
  },
  input: {
    flex: 1,
    height: 48,
  },
  clearButton: {
    padding: 8,
  },
  clearButtonText: {
    fontSize: 18,
    color: '#999',
  },
});

5. 性能优化

1. 避免不必要的重新渲染

  • 使用 React.memo 包装输入组件,避免不必要的重新渲染
  • 避免在 render 方法中创建新的回调函数
jsx
import React, { memo, useCallback } from 'react';
import { TextInput, StyleSheet } from 'react-native';

const MemoizedInput = memo(({ value, onChangeText, placeholder }) => {
  console.log('MemoizedInput rendered');
  return (
    <TextInput
      style={styles.input}
      value={value}
      onChangeText={onChangeText}
      placeholder={placeholder}
    />
  );
});

export default function OptimizedInput() {
  const [text, setText] = useState('');
  
  const handleChangeText = useCallback((value) => {
    setText(value);
  }, []);

  return (
    <View>
      <MemoizedInput
        value={text}
        onChangeText={handleChangeText}
        placeholder="Enter text"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    margin: 20,
  },
});

2. 防抖处理

  • 对于需要实时验证的输入,使用防抖处理
  • 避免频繁的验证或API调用
jsx
import { View, TextInput, StyleSheet, Text } from 'react-native';
import { useState, useCallback, useRef } from 'react';

export default function DebouncedInput() {
  const [text, setText] = useState('');
  const [debouncedText, setDebouncedText] = useState('');
  const debounceTimeout = useRef(null);

  const handleChangeText = useCallback((value) => {
    setText(value);
    
    // 清除之前的定时器
    if (debounceTimeout.current) {
      clearTimeout(debounceTimeout.current);
    }
    
    // 设置新的定时器
    debounceTimeout.current = setTimeout(() => {
      setDebouncedText(value);
      // 这里可以进行验证或API调用
      console.log('Debounced text:', value);
    }, 500);
  }, []);

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        value={text}
        onChangeText={handleChangeText}
        placeholder="Enter text"
      />
      <Text style={styles.debouncedText}>Debounced text: {debouncedText}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    marginBottom: 16,
  },
  debouncedText: {
    fontSize: 16,
  },
});

6. 常见错误与解决方案

错误 1:输入框不显示

错误

jsx
import { View, TextInput } from 'react-native';
import { useState } from 'react';

export default function App() {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        value={text}
        onChangeText={setText}
        placeholder="Enter text"
        // 错误:没有设置样式
      />
    </View>
  );
}

解决方案

jsx
import { View, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function App() {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        style={styles.input}
        value={text}
        onChangeText={setText}
        placeholder="Enter text"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    margin: 20,
  },
});

错误 2:多行输入框高度问题

错误

jsx
import { View, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function App() {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        style={styles.input}
        value={text}
        onChangeText={setText}
        placeholder="Enter text"
        multiline
        // 错误:没有设置高度或 numberOfLines
      />
    </View>
  );
}

const styles = StyleSheet.create({
  input: {
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    margin: 20,
  },
});

解决方案

jsx
import { View, TextInput, StyleSheet } from 'react-native';
import { useState } from 'react';

export default function App() {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        style={styles.input}
        value={text}
        onChangeText={setText}
        placeholder="Enter text"
        multiline
        numberOfLines={4}
        textAlignVertical="top"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  input: {
    height: 120,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    paddingTop: 10,
    margin: 20,
  },
});

错误 3:键盘遮挡输入框

错误:输入框位于屏幕底部,当键盘弹出时会被遮挡

解决方案

  • 使用 KeyboardAvoidingView 组件
  • 或者使用 ScrollView 包装输入框
jsx
import { View, TextInput, StyleSheet, KeyboardAvoidingView, Platform, ScrollView } from 'react-native';
import { useState } from 'react';

export default function App() {
  const [text, setText] = useState('');

  return (
    <KeyboardAvoidingView
      style={styles.container}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
    >
      <ScrollView contentContainerStyle={styles.scrollContent}>
        <View style={styles.spacer} />
        <TextInput
          style={styles.input}
          value={text}
          onChangeText={setText}
          placeholder="Enter text"
        />
      </ScrollView>
    </KeyboardAvoidingView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollContent: {
    flexGrow: 1,
  },
  spacer: {
    flex: 1,
  },
  input: {
    height: 40,
    borderWidth: 1,
    borderColor: '#ccc',
    paddingHorizontal: 10,
    margin: 20,
  },
});

7. 最佳实践

1. 输入框设计

  • 为输入框添加适当的标签和占位符
  • 使用合适的键盘类型
  • 为不同类型的输入提供相应的验证

2. 用户体验

  • 处理键盘遮挡问题
  • 提供实时反馈和错误提示
  • 实现输入验证和自动完成

3. 性能优化

  • 使用 React.memo 包装输入组件
  • 对于需要实时验证的输入,使用防抖处理
  • 避免在 render 方法中创建新的回调函数

4. 可访问性

  • 为输入框添加适当的 accessibilityLabel
  • 确保输入框有足够的对比度
  • 支持屏幕阅读器

8. 总结

TextInput 是 React Native 中用于接收用户输入的核心组件。通过合理使用 TextInput 组件,你可以创建出各种类型的输入界面。

在使用 TextInput 组件时,要注意:

  1. 为输入框设置适当的样式和高度
  2. 选择合适的键盘类型
  3. 处理键盘遮挡问题
  4. 实现输入验证和错误提示
  5. 考虑性能优化,特别是对于实时验证的输入

掌握 TextInput 组件的使用,是创建交互式 React Native 应用的基础。在接下来的教程中,我们将学习更多的核心组件,如 ScrollViewButton 等。

© 2026 编程马·菜鸟教程 版权所有