我们如何将 Chakra RangeSlider 值传递到 Formik 中?

问题描述 投票:0回答:2

我正在尝试使用 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的值...?

onchange formik chakra-ui rangeslider
2个回答
0
投票

对我有用的例子:

                    <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>

主要技巧是使用查克拉领域


0
投票

有两种方法可以解决这个问题:-

  1. 如果您将元素包装在另一个组件中(这是您的情况)。 在这种情况下,您将 field props 传递给元素并使用 useField() 钩子你可以在助手中获取 setValue() 。您可以使用元中的值 和来自助手的 setValue ,您不必创建一个新状态来 维持这一点。如果你想给它 intialValues 只需将其传递到 Formik 提供商。
  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

  1. 如果您没有将该元素包装在另一个组件中。在这种情况下, 您可以覆盖您的元素(使用字段作为子项)并且您 可以有一个回调函数作为子函数,其中渲染 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>
    
© www.soinside.com 2019 - 2024. All rights reserved.