【问题标题】:react hook form multiple control on one Controller在一个控制器上反应钩子形成多个控制
【发布时间】:2022-09-23 15:28:53
【问题描述】:

我有一个文本输入组件,它使用来自 react native paper 的文本输入,我想通过调用 google place autocomplete API 来自动完成一个地方

现在我可以显示建议,但我无法使用已单击的建议值更改文本输入值 screenshot of component

因为我从反应钩子表单中使用控制器,所以我认为我可以使用 useForm 中的 setValue 来更改值,但是当我尝试调用 setValue 将 textInput 值更改为建议值之一时它没有做任何事情

import React from \"react\";
import { FlatList, StyleSheet, TouchableOpacity, View } from \"react-native\";
import { Text, TextInput, Colors } from \"react-native-paper\";
import { Controller, useForm } from \"react-hook-form\";
import axiosInstance from \"services/axiosInstance\";

export default React.forwardRef(
  (
    {
      name,
      label,
      placeholder,
      control,
      style: addOnStyle,
      ...props
    },
    ref
  ) => {
    const { setValue } = useForm();

    const [addressList, setAddressList] = React.useState([])
    const getAddressList = async (input) => {
        if (input == null || input.match(/^ *$/) !== null) {
            setAddressList([])
        } else {
            const response = await axiosInstance.get(
                `https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${input}&components=country:us&language=en&key=API_KEY`
                )
            setAddressList([])
            if (response?.data?.status === \"OK\") {
                response?.data?.predictions?.map((item) => setAddressList(addressList => [...addressList, item.description]))
            } else {
                setAddressList([\"Address not found.\"])
            }
        }
    }

    return (
      <View style={{ ...styles.viewInput, ...addOnStyle }}>
<Controller
  control={control}
  name={name}
  defaultValue=\"\"
  render={({
   field: { onChange, onBlur, value, name },
   fieldState: { error },
  }) => {
   return (
    <>
     <TextInput
      label={label}
      name={name}
      placeholder={placeholder}
      onBlur={onBlur}
      onChangeText={(val) => onChange(val, getAddressList(val))}
      error={!!error?.message}
      value={value}
      ref={ref}
      {...props}
     />
     {error?.message ? (
      <Text style={styles.textError}>{error?.message}</Text>
     ) : null}
     {addressList.length > 0 ?
       <View style={styles.addressListContainer}>
         <FlatList
           keyExtractor={(_, i) => String(i)}
           data={addressList}
           renderItem={({ item, index }) => {
            return (
             <TouchableOpacity 
               activeOpacity={1} 
               style={[styles.addressListItem, index==0 ? {borderTopWidth: 0} : {borderTopWidth: 1}]}
               onPress={() => {setAddressList([]), setValue(name, item)}}
             >
              <Text numberOfLines={1}>{item}</Text>
             </TouchableOpacity>
            )
          }}
        />
       </View>
     : null}
   </>
  );
 }}
/>
</View>
    );
  }
);

更新更改标题以匹配当前问题

我认为现在我的问题是因为控件是从组件外部设置的,这使得它不能从组件内部使用 setValue 进行更改,现在我想知道我们是否可以在一个控制器上使用多个控件?

  • 更新:添加了我的组件的完整代码
  • 我认为您在导致问题的组件内部使用setValue 是正确的。 controlsetValue 来自 2 个不同的 useForm 挂钩实例。所以,它可能行不通。尝试将setValue 作为道具传递或使用control 来自useForm 钩子内部组件。

标签: react-native react-hook-form


【解决方案1】:
onChangeText={(val) => onChange(val, getAddressList(val))}

在这里,你应该写 (newText) 而不是 val。 所以最终的代码看起来像:

onChangeText={newText=> onChange(newText, getAddressList(newText))}

【讨论】:

  • 它没有做任何事情,我认为我的问题出在 touchableopacity 内的 onpress 电话上
  • 你在 onPress() 上做了 setAddressList([])。地址列表将为空。因此,当您在 onChangeText() 上调用 getAddressList(val) 时,您将一无所获。
  • 这里好像有个误区,调用getAddressList(val)调用google API来显示地址建议,而onPress()上的setAddressList([])是清除地址列表,需要在我的时候关闭建议模态选择建议(见附图)
  • 如果您查看随附的屏幕截图,我的问题是当我尝试单击其中一个建议时它没有做任何事情,而我的期望是将我的 textInput 的值更改为我选择的建议的值。我已经更新了我的代码以显示我的组件的完整代码
【解决方案2】:

我通过将 onPress 上的 setValue(name, item) 更改为 onChange(item) 来解决它,它不需要其他控件

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多