我正在尝试使用 Formik 将数据传递到带有脉轮范围滑块的注册表单中。我无法将更改后的值传递到我的handleSignUp() 函数中。他们总是只显示初始价格范围值。
<Formik
initialValues={{
name: '',
email: '',
password: '',
priceRange: [500, 1200],
}}
onSubmit={(values: any) => handleSignUp(values)}
validationSchema={Yup.object().shape({
name: Yup.string().required(),
email: Yup.string().required().email(),
password: Yup.string().required().min(6),
priceRange: Yup.array().required(),
})}
>
{({
values,
touched,
errors,
dirty,
isSubmitting,
handleChange,
handleBlur,
handleSubmit,
handleReset,
}) => {
return (
<Form onSubmit={handleSubmit}>
<VStack border="1px" borderColor="gray.200" p="2em">
<FormControl isInvalid={!!errors.email && !!touched.email}>
<FormLabel htmlFor="name">Name</FormLabel>
<Input
id="name"
type="name"
value={values.name}
onChange={handleChange}
onBlur={handleBlur}
/>
<FormLabel htmlFor="email">Email</FormLabel>
<Input
id="email"
type="email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
/>
<FormLabel pt="1em" htmlFor="password">
Password
</FormLabel>
<Input
id="password"
type="password"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
/>
<FormLabel pt="1em" htmlFor="price range">
Preferred Price Range
</FormLabel>
<Field
name="priceRange"
as={RangeSliderElement}
title="Preferred Price Range"
min={100}
defaultMin={500}
defaultMax={1000}
max={1500}
step={50}
/>
<FormErrorMessage>{errors.email}</FormErrorMessage>
</FormControl>
<Button
mt="2em"
type="submit"
isDisabled={isSubmitting}
colorScheme="purple"
w="100%"
>
Sign Up {'>>'}
</Button>
</VStack>
<HStack w="100%" py="1rem" justifyContent="center">
<Text>Already on the list? </Text>
<Button
type="button"
onClick={() => {
setloginNotSignUp(true);
}}
isDisabled={isSubmitting}
variant="ghost"
>
Sign In
</Button>
</HStack>
</Form>
);
}}
</Formik>
我的范围滑块如下所示:
const [limit, setLimit] = useState<Array<any>>([defaultMin, defaultMax]);
const onChangeLimit = (val: any) => {
setLimit(val);
};
return (
<RangeSlider
name={name}
defaultValue={[defaultMin, defaultMax]}
colorScheme="blue"
size="lg"
min={min}
max={max}
step={step}
onChangeEnd={onChangeLimit}
>
<RangeSliderTrack
height="10px"
borderRadius="5px"
border="1px solid #1F2023"
bg="#FFFFFF"
>
<RangeSliderFilledTrack />
</RangeSliderTrack>
<Tooltip
label={formatPrice(limit[0])}
bg="white"
border="1px solid gray"
color="black"
placement="bottom"
pl={2}
pr={2}
isOpen
>
<RangeSliderThumb
index={0}
w="25px"
h="25px"
borderColor="gray"
border="1px solid"
borderRadius="5px"
sx={{
':focus': {
boxShadow: '0 0 3px #fff',
},
}}
>
<FaGripLinesVertical color="gray" />
</RangeSliderThumb>
</Tooltip>
<Tooltip
label={formatPrice(limit[1])}
bg="white"
border="1px solid gray"
color="black"
placement="bottom"
pl={3}
pr={3}
isOpen
>
<RangeSliderThumb
index={1}
w="25px"
h="25px"
borderColor="gray"
border="1px solid"
borderRadius="5px"
sx={{
':focus': {
boxShadow: '0 0 3px #fff',
},
}}
>
{' '}
<FaGripLinesVertical color="gray" />
</RangeSliderThumb>
</Tooltip>
</RangeSlider>
);
我尝试将handleChange函数传递到rangeslider onChange属性中,但要么它没有正确传递,要么我不知道如何访问它。我以为formik会自动将值传递到Field组件中,但是我看不到在哪里调整onChange的值...?
对我有用的例子:
<Field name='price'>
{({field, form}) => (
<>
<Text color={'gray.500'} size="sm">
£{field?.value[0]} - £{field?.value[1]}
</Text>
<FormControl display='flex' alignItems='center'>
<RangeSlider {...field} name={'price'}
defaultValue={[field?.value[0], field?.value[1]]} onChange={(val) =>
form.setFieldValue(field.name, val)
}
value={formik.values.price}>
<RangeSliderTrack bg='red.100'>
<RangeSliderFilledTrack bg='tomato'/>
</RangeSliderTrack>
<RangeSliderThumb boxSize={6} index={0}>
<Box color='tomato' as={MdGraphicEq}/>
</RangeSliderThumb>
<RangeSliderThumb boxSize={6} index={1}>
<Box color='tomato' as={MdGraphicEq}/>
</RangeSliderThumb>
</RangeSlider>
</FormControl>
</>
)}
</Field>
主要技巧是使用查克拉领域
有两种方法可以解决这个问题:-
const [field, meta, helpers] = useField(props.name);
const { value } = meta;
const { setValue } = helpers;
const onChangeLimit = (val: any) => {
setLimit(val);
};
//rest of the code from RangeSliderElement
如果您没有将该元素包装在另一个组件中。在这种情况下, 您可以覆盖您的元素(使用字段作为子项)并且您 可以有一个回调函数作为子函数,其中渲染 props 是一个包含字段、表单和元的对象。如果你安慰所有人 三个组成部分然后你会发现 2 个函数,setFieldValue 和 设定值。使用 setFieldValue 您可以设置字段的值( @Wayneio 正在使用),您可以设置该字段的值并使用 setValue 在这里,您可以重置整个表单的值。那将是 像这样的:
<Field name="priceRange">
{({field, form, meta}) => {
return (<>
// code for range slider and in onChange use
form.setValues() or form.setFieldValue()
</>)
}}
</Field>