0
votes

I've read a number of questions on this same error but couldn't understand whats happening in my case. On the other questions this error is caused by an object being used as a React child or caused by more than one prop attribute being passed.

I'm trying to set formik and yup to validate a Day Field according to a Month Field, both using react-select, in such way that if the month is February then the max day allowed is 29. Just that...

I've managed to reproduce the error in a Codesandbox: https://codesandbox.io/s/formik-yup-reactselect-rmd9f?file=/src/App.js

If you select the Day 29 and any month, then it works, but if you select day 30 and February then this error appears and I can't find out what's wrong:

Uncaught Error: Objects are not valid as a React child (found: object with keys {value}). If you meant to render a collection of children, use an array instead.

The code is:

import { Button } from "@chakra-ui/button";
import {
  FormControl,
  FormErrorMessage,
  FormLabel,
} from "@chakra-ui/form-control";
import { Center, Stack } from "@chakra-ui/layout";
import { Formik, Form, useField, useFormikContext } from "formik";
import * as Yup from "yup";
import Select from "react-select";

const SelectInput = ({ label, options, ...props }) => {
  const [field, meta, helper] = useField(props);
  const { values, setFieldValue } = useFormikContext();

  return (
    <FormControl id={props.id} isInvalid={meta.touched && meta.error}>
      <FormLabel>{label}</FormLabel>
      <Select
        {...field}
        {...props}
        options={options}
        onBlur={helper.setTouched}
        value={values[field.name]}
        onChange={(value) => setFieldValue(field.name, value)}
      />
      <FormErrorMessage>{meta.error}</FormErrorMessage>
    </FormControl>
  );
};

const SignupForm = () => {
  const days = [
    { value: 29, label: "29" },
    { value: 30, label: "30" },
  ];
  const months = [
    { value: 0, label: "January" },
    { value: 1, label: "February" },
  ];

  return (
    <Formik
      initialValues={{
        day: "",
        month: "",
      }}
      validationSchema={Yup.object({
        day: Yup.object()
          .shape({
            value: Yup.number().required(),
            label: Yup.string().required(),
          })
          .when("month", {
            is: (month) => {
              return month?.value === 1;
            },
            then: Yup.object().shape({
              value: Yup.number()
                .required()
                .max(29, `This month has only 29 days`),
              label: Yup.string().required(),
            }),
          }),
        month: Yup.object().shape({
          value: Yup.number().required(),
          label: Yup.string().required(),
        }),
      })}
      onSubmit={(values, { setSubmitting }) => {
        alert(JSON.stringify(values, null, 2));
        setSubmitting(false);
      }}
    >
      <Form>
        <Center>
          <Stack
            spacing={4}
            padding={4}
            width="50%"
          >
            <SelectInput
              label="Day"
              name="day"
              type="text"
              options={days}
              instanceId="unique"
            />
            <SelectInput
              label="Month"
              name="month"
              type="text"
              options={months}
              instanceId="unique"
            />
            <Button type="submit"> Register </Button>
          </Stack>
        </Center>
      </Form>
    </Formik>
  );
};

export default SignupForm;

Any help would be appreciated :P

1

1 Answers

1
votes

meta.error is not guaranteed to be a string.

If you change

<FormErrorMessage>{meta.error}</FormErrorMessage>

to

<FormErrorMessage>{JSON.stringify(meta.error)}</FormErrorMessage>

it renders alright.

Doesn't show the error, either, though...