Search code examples
reactjsnext.jsreact-hook-formreact-queryreact-day-picker

Not able to set initial dates using react day picker and Next.js


I am using Next.js, React Query and React Day Picker with React Hook Form.

I am fetching some dates from an endpoint using React Query and I want to set these dates as the initial dates that are picked. If I navigate around the site and go to the page the dates show up as selected. However, if I refresh the page no dates appear. I have to navigate to another page and navigate back to see the selected dates.

  const {
    data: initialDatesTest,
    error,
    isLoading,
  } = useQuery({
    queryKey: ["dates"],
    queryFn: getDates,
  });
  async function getDates() {
    const response = await fetch("/api/dates-to-exclude");
    const data = await response.json();
    const parsedExcludedDates = data.excludedDates.PartyExcludeDates.map(
      (dateString: string) => new Date(dateString)
    );

    return parsedExcludedDates;
  }

const initialDays: Date[] = initialDatesTest || [];
const [days, setDays] = useState<Date[] | undefined>(initialDays);


      <Controller
        control={control}
        name="DayPicker"
        render={({ field }) => (
          <DayPicker
            mode="multiple"
            min={1}
            selected={days}
            onSelect={setDays}
            footer={footer}
            disabled={{ before: new Date() }}
            numberOfMonths={1}
          />
        )}
      />

Solution

  • That's because initialDatesTest is undefined before the data has been fetched, and the initial value is only set on the first render. You want to call setDays in the onSuccess of useQuery. Something like

    const {
      data: initialDatesTest,
      error,
        isLoading,
    } = useQuery({
      queryKey: ["dates"],
      queryFn: getDates,
    });
    
    async function getDates() {
      const response = await fetch("/api/dates-to-exclude");
      const data = await response.json();
      const parsedExcludedDates = data.excludedDates.PartyExcludeDates.map(
        (dateString: string) => new Date(dateString)
      );
    
      setDates(parsedExcludedDates); // update state to reflect what was returned from server.
    
      return parsedExcludedDates;
    }