skip to Main Content

I am creating an application with dayjs as the date-time library. In the application I am setting the default locale to "en" at the app level and when I am changing the language in the dropdown, I update the locale. For some reason the locale change is not reflecting inside the app. I am rendering ja locale on the Japanese language selection. What am I doing wrong?

import Component1 from "./Component1";
import Component2 from "./Component2";
import { useEffect, useState } from "react";
import { setLocale } from "./time";

const languageOptions = [
  {
    name: "English",
    value: "en",
  },
  {
    name: "Japanese",
    value: "ja",
  },
];

export default function App() {
  const [language, setLanguage] = useState("en");

  useEffect(() => setLocale("en"), []);

  const handleChange = (e) => {
    setLocale(e.target.value);
    setLanguage(e.target.value);
  };

  return (
    <div>
      <h1>Dayjs </h1>
      <select onChange={handleChange}>
        {languageOptions.map(({ name, value }) => (
          <option value={value} selected={language === value}>
            {name}
          </option>
        ))}
      </select>
      <Component1 />
      <Component2 />
    </div>
  );
}
import dayjs from "dayjs";
import("dayjs/locale/en");
import("dayjs/locale/ja");

export const formats = {
  LONG_DATE: "LL",
  FULL_DATE_TIME: "LLL",
};

export function setLocale(locale) {
  dayjs.locale(locale);
}

export function getFormat(timestamp, format) {
  return dayjs(timestamp).format(format);
}

export function getCurrentFormat(format) {
  return dayjs().format(format);
}
import { getFormat, formats } from "./time";

export default function Component1() {
  return <h1>Time 1: {getFormat(1721306110, formats.FULL_DATE_TIME)}</h1>;
}


import { getCurrentFormat } from "./time";

export default function Component2() {
  return <h1>Time 2: {getCurrentFormat()} </h1>;
}

2

Answers


  1. I think it’s because of dayjs.locale() does not trigger a re-render of your components.
    You need to pass the language state as a prop to your components and then use the language prop inside the components to format the dates.

    Try this
    App component :

    import Component1 from "./Component1";
    import Component2 from "./Component2";
    import { useEffect, useState } from "react";
    import { setLocale } from "./time";
    
    const languageOptions = [
      {
        name: "English",
        value: "en",
      },
      {
        name: "Japanese",
        value: "ja",
      },
    ];
    
    export default function App() {
      const [language, setLanguage] = useState("en");
    
      useEffect(() => {
        setLocale(language);
      }, [language]);
    
      const handleChange = (e) => {
        setLocale(e.target.value);
        setLanguage(e.target.value);
      };
    
      return (
        <div>
          <h1>Dayjs </h1>
          <select onChange={handleChange} value={language}>
            {languageOptions.map(({ name, value }) => (
              <option key={value} value={value}>
                {name}
              </option>
            ))}
          </select>
          <Component1 language={language} />
          <Component2 language={language} />
        </div>
      );
    }
    

    Component 1 :

    import { getFormat, formats } from "./time";
    
    export default function Component1({ language }) {
      return <h1>Time 1: {getFormat(1721306110, formats.FULL_DATE_TIME)}</h1>;
    }
    

    Components 2

    import { getCurrentFormat } from "./time";
    
    export default function Component2({ language }) {
      return <h1>Time 2: {getCurrentFormat()} </h1>;
    }
    
    Login or Signup to reply.
  2. I am assuming when you say change locale you also want to change timezone.

    If so, Dayjs requires lot of nonsense.
    Try something like this.

       import dayjs from "dayjs";
    import "dayjs/locale/en";
    import "dayjs/locale/ja";
    import utc from "dayjs/plugin/utc";
    import timezone from "dayjs/plugin/timezone";
    import dayjsRelativeTime from "dayjs/plugin/relativeTime";
    
    dayjs.extend(utc);
    dayjs.extend(timezone);
    dayjs.extend(dayjsRelativeTime);
    const now = String(Date.now());
    
    export const formats = {
      LONG_DATE: "LL",
      FULL_DATE_TIME: "LLL",
    };
    
    export function setLocale(locale) {
      dayjs.tz.setDefault(locale === "ja" ? "Asia/Tokyo" : "Europe/London");
    }
    
    export function getFormat(timestamp, format) {
      return dayjs(timestamp).format(format);
    }
    
    export function getCurrentFormat(language) {
      return dayjs(Number(now)).tz().format();
    }
    

    Hope this helps! If not let me know what i missed.

    english time
    Japan time

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search