You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native+TypeScript自定义TextInput组件类型错误求助

React Native + TypeScript 自定义TextInput组件类型错误解决

问题描述

我正尝试在React Native框架中使用TypeScript创建文本表单,自定义了用于邮箱、密码输入的TextInput组件,以下是我的代码:

TextInput.tsx

interface TextInputGroup extends ComponentPropsWithoutRef<"input"> {
  errorText: string;
  description: string;
}

export default function TextInput({ errorText, description, ...props } : TextInputGroup) {
  return (
    <View style={styles.container}>
      <Input
        style={styles.input}
        selectionColor={theme.colors.primary}
        underlineColor="transparent"
        mode="outlined"
        {...props}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  input: {
    backgroundColor: theme.colors.surface,
  },
})

SignUp.tsx

export default function RegisterScreen({ navigation } : { navigation : any }) {
  const [name, setName] = useState({ value: '', error: '' })
  const [email, setEmail] = useState({ value: '', error: '' })
  const [password, setPassword] = useState({ value: '', error: '' })

  return (
    <Background>
      <TextInput
        label="Name"
        returnKeyType="next"
        value={name.value}
        onChangeText={(text) => setName({ value: text, error: '' })}
        error={!!name.error}
        errorText={name.error}
      />
    </Background>
  )
}

出现的核心类型问题:

  • 自定义组件继承了Web端HTML input的属性类型,和React Native UI库的Input组件不匹配
  • 自定义组件要求必填的description属性未在父组件中传递
  • 父组件传递的error属性未在自定义组件接口中定义

修复方案

1. 修正组件属性的继承类型

你继承的ComponentPropsWithoutRef<"input">是Web端input元素的属性,若使用的是react-native-paper的Input组件,需替换为对应库的属性类型:

import { Input, InputProps } from 'react-native-paper';

// 继承Input组件的原生属性,再扩展自定义属性
interface TextInputGroup extends InputProps {
  errorText: string;
  description?: string; // 设为可选,避免父组件必须传递
  error?: boolean; // 添加父组件传入的error属性
}

2. 完善自定义TextInput组件的渲染逻辑

把error状态传递给底层Input,并渲染错误文本和描述文本:

export default function TextInput({ errorText, description, error, ...props } : TextInputGroup) {
  return (
    <View style={styles.container}>
      <Input
        style={styles.input}
        selectionColor={theme.colors.primary}
        underlineColor="transparent"
        mode="outlined"
        error={error}
        {...props}
      />
      {/* 渲染描述文本 */}
      {description && <Text style={styles.description}>{description}</Text>}
      {/* 渲染错误文本 */}
      {error && <Text style={styles.errorText}>{errorText}</Text>}
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    marginBottom: 16,
  },
  input: {
    backgroundColor: theme.colors.surface,
  },
  description: {
    fontSize: 12,
    color: theme.colors.onSurfaceVariant,
    marginTop: 4,
  },
  errorText: {
    fontSize: 12,
    color: theme.colors.error,
    marginTop: 4,
  },
})

3. 优化SignUp.tsx的导航类型

替换navigation: any为更严谨的类型(以react-navigation为例):

import { NavigationProp } from '@react-navigation/native';

export default function RegisterScreen({ navigation } : { navigation : NavigationProp<any> }) {
  const [name, setName] = useState({ value: '', error: '' })
  const [email, setEmail] = useState({ value: '', error: '' })
  const [password, setPassword] = useState({ value: '', error: '' })

  return (
    <Background>
      <TextInput
        label="Name"
        returnKeyType="next"
        value={name.value}
        onChangeText={(text) => setName({ value: text, error: '' })}
        error={!!name.error}
        errorText={name.error}
        // 可选:如果需要传递description则添加
        // description="Enter your full name"
      />
    </Background>
  )
}

内容的提问来源于stack exchange,提问作者Tran Tai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:14:54