fix: react-hook-form Controller crash with special characters in field names (#5715)

This commit is contained in:
heheer
2025-09-27 19:24:12 +08:00
committed by GitHub
parent a6ba974167
commit ce3556c240
2 changed files with 25 additions and 14 deletions

View File

@@ -217,20 +217,31 @@ const RenderUserFormInteractive = React.memo(function RenderFormInput({
const defaultValues = useMemo(() => { const defaultValues = useMemo(() => {
if (interactive.type === 'userInput') { if (interactive.type === 'userInput') {
return interactive.params.inputForm?.reduce((acc: Record<string, any>, item) => { return interactive.params.inputForm?.reduce((acc: Record<string, any>, item, index) => {
acc[item.label] = !!item.value ? item.value : item.defaultValue; acc[`field_${index}`] = !!item.value ? item.value : item.defaultValue;
return acc; return acc;
}, {}); }, {});
} }
return {}; return {};
}, [interactive]); }, [interactive]);
const handleFormSubmit = useCallback((data: Record<string, any>) => { const handleFormSubmit = useCallback(
onSendPrompt({ (data: Record<string, any>) => {
text: JSON.stringify(data), const finalData: Record<string, any> = {};
isInteractivePrompt: true interactive.params.inputForm?.forEach((item, index) => {
}); const fieldName = `field_${index}`;
}, []); if (fieldName in data) {
finalData[item.label] = data[fieldName];
}
});
onSendPrompt({
text: JSON.stringify(finalData),
isInteractivePrompt: true
});
},
[interactive.params.inputForm]
);
return ( return (
<Flex flexDirection={'column'} gap={2} w={'250px'}> <Flex flexDirection={'column'} gap={2} w={'250px'}>

View File

@@ -1,5 +1,5 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { Box, Button, Flex } from '@chakra-ui/react'; import { Box, Flex } from '@chakra-ui/react';
import { Controller, useForm, type UseFormHandleSubmit } from 'react-hook-form'; import { Controller, useForm, type UseFormHandleSubmit } from 'react-hook-form';
import Markdown from '@/components/Markdown'; import Markdown from '@/components/Markdown';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
@@ -79,12 +79,12 @@ export const FormInputComponent = React.memo(function FormInputComponent({
}); });
const RenderFormInput = useCallback( const RenderFormInput = useCallback(
({ input }: { input: UserInputFormItemType }) => { ({ input, index }: { input: UserInputFormItemType; index: number }) => {
return ( return (
<Controller <Controller
key={input.label} key={input.label}
control={control} control={control}
name={input.label} name={`field_${index}`}
rules={{ required: input.required }} rules={{ required: input.required }}
render={({ field: { onChange, value }, fieldState: { error } }) => { render={({ field: { onChange, value }, fieldState: { error } }) => {
const inputType = nodeInputTypeToInputType([input.type]); const inputType = nodeInputTypeToInputType([input.type]);
@@ -94,7 +94,7 @@ export const FormInputComponent = React.memo(function FormInputComponent({
inputType={inputType} inputType={inputType}
value={value} value={value}
onChange={onChange} onChange={onChange}
placeholder={input.description} placeholder={input.label}
isDisabled={submitted} isDisabled={submitted}
isInvalid={!!error} isInvalid={!!error}
maxLength={input.maxLength} maxLength={input.maxLength}
@@ -114,14 +114,14 @@ export const FormInputComponent = React.memo(function FormInputComponent({
<Box> <Box>
<DescriptionBox description={description} /> <DescriptionBox description={description} />
<Flex flexDirection={'column'} gap={3}> <Flex flexDirection={'column'} gap={3}>
{inputForm.map((input) => ( {inputForm.map((input, index) => (
<Box key={input.label}> <Box key={input.label}>
<Flex alignItems={'center'} mb={1}> <Flex alignItems={'center'} mb={1}>
{input.required && <Box color={'red.500'}>*</Box>} {input.required && <Box color={'red.500'}>*</Box>}
<FormLabel>{input.label}</FormLabel> <FormLabel>{input.label}</FormLabel>
{input.description && <QuestionTip ml={1} label={input.description} />} {input.description && <QuestionTip ml={1} label={input.description} />}
</Flex> </Flex>
<RenderFormInput input={input} /> <RenderFormInput input={input} index={index} />
</Box> </Box>
))} ))}
</Flex> </Flex>