Home > Blockchain >  Can my component name be "Date" while still allowing me to access built-in "new Date(
Can my component name be "Date" while still allowing me to access built-in "new Date(

Time:10-08

I'm going through the NextJS tutorial right now, but with my own twist. In the NextJS example the custom component is called "Date" (/components/date.js) but NO built-in Date() object is being used in processing - so the Date component name is not colliding with anything... it's unique to the file.

However in my case, my component is called "Date" just like in the tutorial... but I also want to use JS built-in "Date object" in the same file during processing (so i have 2 Dates present). It seems when I do "new Date()" now and try to call just the built-in Date object... the component function is getting called instead so it throws error.

I know I can simply re-name my Date to PublishedDate and references to "<PublishedDate>" instead and it work just fine then.

But I wanna know for learning purposes is there a way to have my own component re-use a built-in name i.e Date... is there a way around it that's valid? This is more of a curiosity question so I can properly learn the JS/React/NextJS and understand WHY/WHY-NOT with respect to JS/NextJS/React internals (otherwise I would have just changed the name and be done with it).

date.js

import { format, parse } from "date-fns"

export default function Date({ dateString }) {
  const date = parse(dateString, "LLLL d, yyyy", new Date()) // call built-in Date()????
  return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time>
}

Error thrown:

import { format, parse } from "date-fns"
  2 | 
> 3 | export default function Date({ dateString }) {
    |                               ^
  4 |   const date = parse(dateString, "LLLL d, yyyy", new Date())
  5 |   return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time>
  6 | }
node_modules/next/dist/server/dev/next-dev-server.js:762
error - components/date.js (3:31) @ new Date
node_modules/next/dist/build/output/log.js:33
[31merror[39m - TypeError: Cannot destructure property 'dateString' of 'undefined' as it is undefined.
    at new Date (/Users/cfork/projects/nextjs-blog/components/date.js:3:32)
    at Date (/Users/cfork/projects/nextjs-blog/components/date.js:4:50)

CodePudding user response:

The variable Date inside a function Date(…) {…} will always resolve to just that function. You need two distinct names to refer to the two separate things.

  • One option would be to export an anonymous function declaration, removing the name:

    export default function({ dateString }) {
    //                    ^^
      const date = parse(dateString, "LLLL d, yyyy", new Date())
      return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time>
    }
    
  • another option would be to refer to the global Date not via a variable, but as a property of the global object:

    export default function Date({ dateString }) {
      const date = parse(dateString, "LLLL d, yyyy", new global.Date())
      //                                                 ^^^^^^^
      return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time>
    }
    
  • If the .name of the function is important, use some aliases:

    const GlobalDate = Date;
    const DateComponent = function Date({ dateString }) {
      const date = parse(dateString, "LLLL d, yyyy", new GlobalDate())
      return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time>
    }
    export { DateComponent as default }
    

You can also change the name of the function to something else, like DateComponent or nothing, without changing the names in the other modules under which you import the function. The export is named default, that's all what matters for the other modules.

However, it is in general a bad idea to name things the same as standard globals, it leads to confusing code that will be hard to understand for all developers, yourself included.

CodePudding user response:

Javascript will not allow you to use an inbuilt function as a custom function. Did you try changing the name of the function and try again?

  • Related