Search code examples
reactjsreact-hooksnext.jsuse-statereact-datepicker

Unhandled Runtime Error: Should have a queue. This is likely a bug in React. Please file an issue


Error

I'm facing this error after integrating react-datepicker in my Next.js app. Couldn't be able to fix.

Below some code of my app files:

package.json

  "dependencies": {
    "axios": "^0.21.1",
    "bootstrap": "^5.0.0",
    "i18next": "^20.2.2",
    "i18next-browser-languagedetector": "^6.1.1",
    "next": "10.2.0",
    "react": "16.14.0",
    "react-bootstrap": "^1.6.0",
    "react-datepicker": "^3.2.2",
    "react-dom": "16.14.0",
    "react-dropzone": "^11.3.2",
    "react-i18next": "^11.8.15",
    "react-redux": "^7.2.4",
    "react-redux-toastr": "^7.6.5",
    "reactstrap": "^8.9.0",
    "redux": "^4.1.0",
    "redux-thunk": "^2.3.0",
    "simple-react-validator": "^1.6.0"
  }

_app.jsx

import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'react-datepicker/dist/react-datepicker.css';
import '../styles/globals.css';
import { Provider } from 'react-redux';
import store from '../store';
import Header from '../components/Layouts/Header';
import Footer from '../components/Layouts/Footer';

function MyApp({ Component, pageProps }) {
  return (
    <Provider store={store}>
      <Header />
      <Component {...pageProps} />
      <Footer />
    </Provider>
  );
}

export default MyApp;

/pages/services/insurance/apply/[type].jsx

/* eslint-disable no-case-declarations */
/* eslint-disable no-unused-vars */
import React, { useState, useEffect } from 'react';
import Router, { useRouter } from 'next/router';
import { Container } from 'reactstrap';
import styles from '../../../../styles/Service.module.css';
import Motor from './forms/motor';
import Travel from './forms/travel';
import routes from '../../../../utils/routes';

const Apply = () => {
  const [type, setType] = useState(null);
  const [form, setForm] = useState(null);
  const router = useRouter();

  useEffect(() => {
    if (router.query.type) {
      switch (router.query.type) {
        case 'motor':
          setType(router.query.type);
          setForm(Motor);
          break;
        case 'travel':
          setType(router.query.type);
          setForm(Travel);
          break;
        default:
          Router.push(routes.NOT_FOUND);
      }
    }
  }, [router.query]);

  return (
    <Container className={styles.mk_main_container}>
      <div className={styles.mk_service_container}>
        {form}
      </div>
    </Container>
  );
};

export default Apply;

travel.jsx

import React, { useState } from 'react';
import { Row, Col } from 'reactstrap';
import DatePicker from 'react-datepicker';
import styles from '../../../../../styles/Service.module.css';
import MKLabel from '../../../../../components/Common/Form/Label';
import MKInput from '../../../../../components/Common/Form/Input';
import MKSelect from '../../../../../components/Common/Form/Select';
import MKRadioRounded from '../../../../../components/Common/Form/RadioRounded';
import MKButton from '../../../../../components/Common/Button';
import formStyles from '../../../../../styles/Form.module.css';
import { generateArrayOfYears, generateArrayOfMonths, generateArrayOfDays } from '../../../../../utils/helpers';

const Travel = () => {
  const [startDate, setStartDate] = useState(new Date());

  return (
    <form>
       ...

        <div className="pt-4">
          <MKLabel text="Date of birth?" required />
          <DatePicker
            selected={startDate}
            onChange={(date) => setStartDate(date)}
            isClearable
            placeholderText="I have been cleared!"
          />
        </div>

        ...
    </form>
  );
};

export default Travel;

Directory structure Directory structure


What could be the reason and how can be fixed?


Solution

  • You should be rendering the component object you store in state in Apply, not just using it as a variable.

    const Apply = () => {
      const [type, setType] = useState(null);
      const [form, setForm] = useState(null);
      const router = useRouter();
    
      useEffect(() => {
        // ... elided ...
      }, [router.query]);
      
      // Naming this in PascalCase is important 
      // so React considers it a component
      const FormComponent = form;  
    
      // Early-out when nothing to render.
      if (!FormComponent) return null;
    
      return (
        <Container className={styles.mk_main_container}>
          <div className={styles.mk_service_container}>
            <FormComponent />
          </div>
        </Container>
      );
    };
    

    To make things simpler, though, those don't even need to be state atoms:

    const Apply = () => {
      const router = useRouter();
      const type = router.query.type;
      const FormComponent = null;
      if (type === "motor") FormComponent = Motor;
      if (type === "travel") FormComponent = Travel;
      if (!FormComponent) return null;
      return (
        <Container className={styles.mk_main_container}>
          <div className={styles.mk_service_container}>
            <FormComponent />
          </div>
        </Container>
      );
    };