最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typescript - ReactNative Paper, extend compound component with forwardRef - Stack Overflow

programmeradmin0浏览0评论

I am using ReactNativePaper v4 and having a difficult time extending components with Typescript when using forwardRef and having a compoundcomponent: TextInput.Icon. Here is my current setup:

const InputComponent = forwardRef<
  typeof RNPInput,
  Omit<TextInputProps, 'theme'>
>(({ label, style, ...rest }, ref) => {
  const theme = useTheme();

  return (
    <View>
      {label && <Text>{label}</Text>}
      <RNPInput
        mode="outlined"
        outlineColor={theme.colors.backdrop}
        selectionColor={theme.colors.accent}
        style={style}
        // @ts-ignore
        ref={ref}
        theme={{ colors: { text: styles.input.color } }}
        {...rest}
      />
    </View>
  );
});

const TextInput = Object.assign(InputComponent, {
  Icon: RNPInput.Icon,
});

export { TextInput };

Then I consume like:

const Test = () => {
    return <TextInput  right={<TextInput.Icon name="eye"/>} />
}

The issues I have are:

  1. the compound component props are not found, so name prop is not known.
  2. if I remove the // @ts-ignore, the error is:

Type '(instance: (ComponentType<Pick<TextInputProps & RefAttributes & { mode?: "flat" | "outlined" | undefined; left?: ReactNode; right?: ReactNode; ... 18 more ...; theme: Theme; } & RefAttributes<...>, "label" | ... 123 more ... | "dense"> & { ...; }> & NonReactStatics<...>) | null) => void' is not assignable to type 'string'

  1. If I remove the Omit<TextInputProps, 'theme'> form the component definition, when I consume the component, it has an error:

Property 'theme' is missing in type '{ right: Element; }' but required in type 'Omit<Props, "ref">'.

If I try to change the compound component definition to be more explicit, the Icon is not invoked

// Explicitly type the Icon component
const Icon = (props: TextInputIconProps) => (
  <RNPInput.Icon color="green" {...props} />
);

// Create the compound component
const TextInput = Object.assign(InputComponent, {
  Icon,
});

How can I correctly extend the TextInput from ReactNative paper so that: 1) forwardRef is correctly typed, and 2) Compound component is exported so that the props are known, and 3) remove the @ts-ignore?

I am using ReactNativePaper v4 and having a difficult time extending components with Typescript when using forwardRef and having a compoundcomponent: TextInput.Icon. Here is my current setup:

const InputComponent = forwardRef<
  typeof RNPInput,
  Omit<TextInputProps, 'theme'>
>(({ label, style, ...rest }, ref) => {
  const theme = useTheme();

  return (
    <View>
      {label && <Text>{label}</Text>}
      <RNPInput
        mode="outlined"
        outlineColor={theme.colors.backdrop}
        selectionColor={theme.colors.accent}
        style={style}
        // @ts-ignore
        ref={ref}
        theme={{ colors: { text: styles.input.color } }}
        {...rest}
      />
    </View>
  );
});

const TextInput = Object.assign(InputComponent, {
  Icon: RNPInput.Icon,
});

export { TextInput };

Then I consume like:

const Test = () => {
    return <TextInput  right={<TextInput.Icon name="eye"/>} />
}

The issues I have are:

  1. the compound component props are not found, so name prop is not known.
  2. if I remove the // @ts-ignore, the error is:

Type '(instance: (ComponentType<Pick<TextInputProps & RefAttributes & { mode?: "flat" | "outlined" | undefined; left?: ReactNode; right?: ReactNode; ... 18 more ...; theme: Theme; } & RefAttributes<...>, "label" | ... 123 more ... | "dense"> & { ...; }> & NonReactStatics<...>) | null) => void' is not assignable to type 'string'

  1. If I remove the Omit<TextInputProps, 'theme'> form the component definition, when I consume the component, it has an error:

Property 'theme' is missing in type '{ right: Element; }' but required in type 'Omit<Props, "ref">'.

If I try to change the compound component definition to be more explicit, the Icon is not invoked

// Explicitly type the Icon component
const Icon = (props: TextInputIconProps) => (
  <RNPInput.Icon color="green" {...props} />
);

// Create the compound component
const TextInput = Object.assign(InputComponent, {
  Icon,
});

How can I correctly extend the TextInput from ReactNative paper so that: 1) forwardRef is correctly typed, and 2) Compound component is exported so that the props are known, and 3) remove the @ts-ignore?

Share asked Nov 19, 2024 at 19:14 Phil LucksPhil Lucks 3,9839 gold badges43 silver badges74 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

forwardRef is being deprecated https://react.dev/reference/react/forwardRef

You can just use ref instead

You can import like this

import {TextInput as TextInputReact} from 'react-native';
import {TextInput} from 'react-native-paper';

Then use your ref like this

const ref = useRef<TextInputReact | null>(null);

Then use your react-native-paper TextInput with ref as usual

<TextInput ref={ref}
发布评论

评论列表(0)

  1. 暂无评论