0

I'm writing a custom React hook, and sometimes the values returned are undefined, sometimes not.

When I return them, no problems. When I want to return them using useMemo, it doesn't work. What I'm doing wrong ?

enter image description here

export function useCryptoDevs() {
    (...)
    const { data } = useContractReads((...))

    const numberOfNft = data?.[0]
    const maxNft = data?.[1]
    const presaleStarted = data?.[2]
    const presaleEnded = data?.[3]

    // this doesn't work :/
    // return (useMemo(() => { numberOfNft, maxNft, presaleStarted, presaleEnded }, [numberOfNft, maxNft, presaleStarted, presaleEnded]))

    // this work, returning undefined serverside and the values clientside
    return ({ numberOfNft, maxNft, presaleStarted, presaleEnded })
}
Fabien
  • 97
  • 8

1 Answers1

1

Solution

return (useMemo(() => ({ numberOfNft, maxNft, presaleStarted, presaleEnded }), [numberOfNft, maxNft, presaleStarted, presaleEnded]))

Also I would suggest to add some kind of fallback if data are undefined and then check this value if needed, eg.:

const maxNft = data?.[1] || -1 //or some other "extreme" value

Explanation

First of all, good to know is that these two are equivalent:

() => (...) //Implicit return
() => {return ...} //Explicit return

The first parameter in useMemo hook is expected to be a function, so you have three options:

useMemo(function hi() {return "Hello World"})
useMemo(() => ("Hello World"))
useMemo(() => {return "Hello World"})

Parentheses in arrow functions are (mostly) used to return an object (because all primitives and variables are allowed to be used without parentheses, so the black sheep of the family is just the object)

useMemo(() => 8) //implicit return | single-line
useMemo(() => (8)) //implicit return | multi-line
useMemo(() => {return 8}) //explicit return
//instead of 8, there could be any of the primitives, e.g.: string "Hello World"

const foo = 8;
useMemo(() => foo)
useMemo(() => (foo))
useMemo(() => {return foo})

const bar = {intval: 8, strval: "Hello World"};
useMemo(() => bar)
useMemo(() => (bar))
useMemo(() => {return bar})
//we are returning a variable here, not bare object

But to the interpreter the () => { maxNft, numberOfNft } looks like function with explicit return that I mentioned above: () => { return ... }

So you just have to make it clear that it is an object, some specific returned value, not an function with explicit return

useMemo(() => ({ maxNft, numberOfNft }), []) //implicit return of object
useMemo(() => {return { maxNft, numberOfNft }}, []) //explicit return of object
twice01
  • 161
  • 4
  • Thank you so much !! Why theses parenthesis are needed ? I'm just returning an object... do you have a link/a concept for me to dig my misunderstanding of what exactly happening on this line ? – Fabien Sep 30 '22 at 07:53
  • @Fabien Explanation added, hope that clears things up for you! – twice01 Sep 30 '22 at 09:56
  • Ok everything is clear rn. Thank you very much guy ! – Fabien Oct 01 '22 at 14:36