<div id="root">
@import "https://cdnjs.cloudflare.com/ajax/libs/react-datepicker/4.6.0/react-datepicker.css";

#root > div > button {
  margin-bottom: 1rem;
}
View Compiled
import React from "https://cdn.skypack.dev/[email protected]";
import ReactDOM from "https://cdn.skypack.dev/[email protected]";
import DatePicker from "https://cdn.skypack.dev/[email protected]";
import * as JsJodaCore from "https://cdn.skypack.dev/@js-joda/[email protected]";

const { ZonedDateTime, ChronoUnit } = JsJodaCore;

/**
 * You don't need this, but it helps to make the example more clear
 */
const FormattedErrorStack = (props) => {
  const { error } = props;
  if (!error) {
    throw new Error(`expected the error prop to be truthy`);
  }

  const errorStr = error.stack ? error.stack : error.toString();
  console.error(errorStr);

  return <div style={{ whiteSpace: "pre-line", color: "red" }}>{errorStr}</div>;
};

const CUSTOM_COMPONENT_NAME = "LocalDatePicker";
const LocalDatePicker = (props) => {
  const [error, setError] = React.useState(null);

  const convertToLocalDate = (d) => {
    try {
      var zdt = ZonedDateTime.parse(d.toISOString());
      var startOfDay = zdt.truncatedTo(ChronoUnit.DAYS);
      props.onChange(startOfDay);
    } catch (err) {
      setError(err);
    }
  };

  if (error) {
    console.error(error);
    return (
      <div>
        <h1>Error within {CUSTOM_COMPONENT_NAME}</h1>
        <div>
          If you are seeing this then that means that {CUSTOM_COMPONENT_NAME} is
          not doing the conversion properly and that means that this example
          needs to be updated. Exact error message:
        </div>
        <br />
        <FormattedErrorStack error={error} />
      </div>
    );
  }

  return <DatePicker onChange={convertToLocalDate} preventOpenOnFocus={true} />;
};

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { error };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.error(error, errorInfo);
  }

  render() {
    if (!!this.state.error) {
      // You can render any custom fallback UI
      return (
        <div>
          <h1>Something went wrong.</h1>
          <FormattedErrorStack error={this.state.error} />
        </div>
      );
    }

    return this.props.children;
  }
}

const App = () => {
  const [date, setDate] = React.useState(null);

  return (
    <ErrorBoundary>
      <LocalDatePicker onChange={setDate} />
      {!date ? (
        <h2>Please select a date</h2>
      ) : (
        <div>
          <h2>Selected {CUSTOM_COMPONENT_NAME.replace("Picker", "")}</h2>
          <div>Year: {date.year().toString()}</div>
          <div>Month: {date.month().toString()}</div>
          <div>Day: {date.dayOfMonth().toString()}</div>
          <div>Minutes: not applicable</div>
          <div>Seconds: not applicable</div>
        </div>
      )}
    </ErrorBoundary>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.