将 textInput 元素移动到单独的组件

Posted

技术标签:

【中文标题】将 textInput 元素移动到单独的组件【英文标题】:move textInput element to a separate component 【发布时间】:2021-01-26 22:47:18 【问题描述】:

我有一个使用它的屏幕:

const [searchText, setSearchText] = useState('');

          <Item rounded style=styles.inputItem>
            <Icon
              name="search"
              size=moderateScale(18)
              color="#bdbdbd"
              style=styles.icon
            />
            <Input
              autoFocus=true
              autoCapitalize="none"
              style=styles.inputField
              placeholder="Friend Search"
              keyboardType="default"
              onChangeText=(text: string) => 
                setSearchText(text);
              
            />
          </Item>

我不想在当前屏幕上使用 Input 元素,而是想把它变成一个可重用的组件。像这样的:

type SearchInputProps = 
  handleChange?: any;
;

export const SearchInput: React.FunctionComponent<SearchInputProps> = (handleChange) => 
  return (
    <Item rounded style=styles.inputItem>
      <Icon name='search' size=moderateScale(18) color="#bdbdbd" style=styles.icon/>
      <Input
        autoFocus=true
        autoCapitalize="none"
        style=styles.inputField
        placeholder="Friend Search"
        onChangeText=()=>handleChange
      />
    </Item>
  );
;

但是,我无法弄清楚如何使onChangeText 工作,以便可以在那里设置主屏幕中的const [searchText, setSearchText] = useState(''); 值。有没有可能?

我试图在这里创建一个小吃博览会,但我无法安装原生库https://snack.expo.io/@nhammad/curious-bubblegum

编辑: 设法解决了类型错误,但在调用组件时仍然不知道如何传递setSearchText

type SearchInputProps = React.PropsWithRef<
  handleChange?: any;
>;
export const FieldInput = React.forwardRef<Input, SearchInputProps>(
  ( handleChange ) => 
    return (
      <Item rounded style=styles.inputItem>
        <Icon
          name="search"
          size=moderateScale(18)
          color="#bdbdbd"
          style=styles.icon
        />
        <Input
          autoFocus=true
          autoCapitalize="none"
          style=styles.inputField
          placeholder="Friend Search"
          keyboardType="default"
          onChangeText=handleChange
        />
      </Item>
    );
  ,
);

【问题讨论】:

您希望从消费者组件控制共享Input 的哪些功能? 我只是希望能够在调用它时传递setSearchText(text)之类的东西。这样我就可以使用这个组件在主屏幕上设置状态。 @im_tsm 【参考方案1】:

本质上,您没有正确调用您的函数。更改您的 onChangeText 行:

onChangeText=()=>handleChange

到:

onChangeText=handleChange

或:

// Use this if you need to pass extra parameters from the child (SearchInput) component. 
onChangeText=(event) => handleChange(event, <extra params>)

【讨论】:

更改为 onChangeText=handleChange 会给我 TypeErrors Type 'PropsWithChildren&lt; handleChange?: any; &gt;' is not assignable to type '(text: string) =&gt; void'但无论如何,我将如何在调用时通过setSearchText(text) @Jnl 您的输入不正确; handleChange 是一个函数,因此它的类型应该是,例如,handleChange?: () =&gt; voidhandleChange?: (event: React.ChangeEvent) =&gt; void(取决于 handleChange 的实际签名) 我设法通过添加ref 解决了类型错误,但我仍然不知道如何从另一个屏幕使用该组件到setSearchText。你能看到更新的qs 吗? @secan【参考方案2】:

您可以创建一个可重用的Input 组件,方法是在组件内部包含常见行为,然后通过 props 将 API 公开给消费者组件。这是一个Snack 示例。请检查组件文件夹中的Input 组件。

import React, useState from 'react';
import  StyleSheet, Text, TextInput as RnTextInput, View  from 'react-native';

const Input = (label, onFocus, ...rest) => 
  const [isFocussed, setIsFocussed] = useState(false);

  const handleFocus = () => 
    setIsFocussed(true);
    onFocus && onFocus();
  ;

  return (
    <View style=[styles.container, isFocussed && styles.inputFocused]>
      <Text style=styles.label>label</Text>
      <RnTextInput
        style=styles.input
        onFocus=handleFocus
        ...rest
      />
    </View>
  );


const styles = StyleSheet.create(
  container: 
    margin: 5,
    borderBottomWidth: 1,
    borderBottomColor: '#d3d3d3',
  ,
  label: 
    color: 'red',
  ,
  input: 
    height: 40,
    fontSize: 16,
    paddingLeft: 10,
  ,
  inputFocused: 
    borderBottomColor: 'blue'
  
)

export default Input;

然后像这样使用组件:

<Input
  label="Enter Name"
  onChangeText=text => onChangeText(text)
  onFocus=handleOnFocus
  placeholder="Enter some value"
  value=value
/>

注意:我使用过内置的 React Native TextInput,但根据我最初的印象,native-baseInput 与 RN TextInput 具有相同的 API。

【讨论】:

您能否尝试根据我提供的本机基本输入示例进行修改?会很有帮助的。 我之前没用过native-base。所以如果你能提供一个我可以尝试的小吃的工作示例。 顺便说一句,你在用什么? Expo 还是 RN cli?

以上是关于将 textInput 元素移动到单独的组件的主要内容,如果未能解决你的问题,请参考以下文章

AS3 fl.controls.TextInput 和移动平台

在这种情况下如何使 TextInput 成为一个单独的组件

在 React Native 中使用 TextInput 等组件在样式方面保持 DRY 的最佳实践?

如何将具有自定义属性的组件移动到 QML 中的单独文件

将组件的依赖注入方法移动到 Blazor 服务器端中的分离 CS 库

React:如何将我的 ajax api 调用移动到一个单独的组件中?