很抱歉,因为我对 React Native 还是很陌生。我在用 3rd 方库(react-native-dropdown-picker)替换一些样式不佳的下拉选择器时遇到了这个问题。我能够创建一个非常可行的解决方案,但该表单使用 react-hook-forms 进行提交和验证。目前表明我的可搜索下拉组件仍然是空的,即使它们清楚地显示值
export const ControlledSearchableInput = (
props: ControlledSearchableInputProps
) => {
return (
<Controller
control={props.control}
name={props.name}
defaultValue={props.defaultValue}
render={({ onChange, value }) => (
<SearchableInput
onChange={onChange}
value={value ?? value.name}
dataType={props.dataType}
hideLabel={props.accountType ?? false}
accountType={props.accountType ?? false}
placeholder={props.placeholder ?? ""}
error={props.error}
/>
)}
/>
);
};
export function SearchableInput<T>({
onChange,
value,
dataType,
error,
label,
hideLabel,
groupPosition,
placeholder,
disabled = false,
accountType,
}: SearchableInputProps<T>) {
const [open, setOpen] = useState(false);
const [val, setVal] = useState<string>(value);
const [loading, setLoading] = useState(false);
const getDataAsync = async (search: string) => {
if (search) {
setLoading(true);
switch (dataType) {
case "country":
return (await mobileApiManager.Countries.getCountries({ search }))
.results;
case "state":
return (
(await mobileApiManager.States.getStates({ search })).results ?? []
);
}
} else {
setLoading(false);
return [];
}
};
const currentList = useAsync<SearchableInputType[]>((searchText) =>
getDataAsync(searchText)
);
const listItems = currentList.value
? currentList.value.map((item) => {
return { label: item.name, value: item.id };
})
: [];
const [items, setItems] = useState(listItems);
useEffect(() => {
setItems(listItems);
if (listItems.length >= 0) {
setLoading(false);
}
}, [currentList.value]);
return (
<View style={{ marginBottom: error ? 16 : 8 }}>
<DropDownPicker
open={open}
value={val}
loading={loading}
items={items ?? []}
setOpen={setOpen}
setValue={setVal}
setItems={setItems}
searchable
disabled={disabled}
placeholder={placeholder ?? ""}
searchPlaceholder="Search..."
labelProps={{ numberOfLines: 1 }}
onChangeSearchText={currentList.execute}
listMode="MODAL"
onChangeValue={onChange}
/>
{!!error && <ErrorMessage text={error} />}
</View>
);
}
export default function EditAddresses(props: EditAddressesProps) {
const { fields, append, remove } = useFieldArray({
control: props.control,
name: "addresses",
keyName: "customIDAddr",
});
return (
<View>
<ProfileRowView marginBottom={`${scale(5)}`} marginTop={`${scale(25)}`}>
<NameText margin={"0"}>{getLocalString(Strings.address)}</NameText>
<AddButtonWithLabel
onPress={() => {
append(defaultAddress);
}}
/>
</ProfileRowView>
{fields.map((item: any, index: number) => (
<View
key={`${item.id}${item.uuid}`}
style={{ marginBottom: scale(13) }}
>
//...Other components
<ControlledSearchableInput
accountType
placeholder={getLocalString(Strings.state)}
control={props.control}
name={`addresses[${index}].state`}
dataType={"state"}
// stateId={`addresses[${index}].stateId`}
defaultValue={item.state ?? ""}
error={props.errors?.addresses?.[index]?.state?.message}
/>
//...Other components
<ControlledSearchableInput
control={props.control}
name={`addresses[${index}].country`}
placeholder={"Country"}
dataType={"country"}
// countryId={`addresses[${index}].countryId`}
accountType
defaultValue={item.country ?? ""}
error={props.errors?.addresses?.[index]?.country?.message}
/>
</View>
))}
</View>
);
}
任何帮助将不胜感激