react-hooksreact-usememoobject-destructuring

How can I return an undefined value with useMemo?


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 })
}

Solution

  • 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