skip to Main Content

I have the following custom hook that basically fetches data from a smart contract:

export const usePoolLength = () => {
    const [length, setLength] = useState(0);

    const _getPoolLength = useCallback(async () => {
        const poolLength = await getPoolLength();
        setLength(poolLength);
    }, [])

    useMemo(() => {
        _getPoolLength();
    }, [_getPoolLength]);

    return { length }
}

export const getPoolLength = async () => {
   const poolLength = await masterchefV2Contract.poolLength();
   return poolLength.toNumber();
}

I understand that calling an API is a side effect but should I be using useEffect or useMemo? It seems like there is no difference so I’m not thinking about changing to useEffect. Wanted to get some opinions/advise, thank you!

4

Answers


  1. The useCallback / useMemo combination here seems a little tangled. useEffect is more straightforward, perhaps easier to read:

    useEffect(() => {
        getPoolLength().then(setLength);
        // or getPoolLength().then(fetchedLength => setLength(fetchedLength));
    }, []);
    
    Login or Signup to reply.
  2. I think it is clearly mentioned in the docs:

    Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.

    Also consider the fact that _getPoolLength is not being used anywhere else. It is a method that is only useful for the API call so why not define it inside the effect and use it there only.

    Login or Signup to reply.
  3. Why do you actually use useCallback with useMemo in combination with useState ?

    I think you should just use the useMemo hook like this:

    const length = useMemo(async () => {
        await _getPoolLength()
    }, [_getPoolLength]); 
    
    Login or Signup to reply.
  4. As long as your custom hook doesn’t need to refetch the data.

    export const usePoolLength = () => {
        const [length, setLength] = useState(0);
        // Your refrence is same throught the lifecycle
        const _getPoolLength = useCallback(async () => {
            const poolLength = await getPoolLength();
            setLength(poolLength);
            return poolLength;
        }, [])
       // Cached value and value available during  render itself.
       const poolLength = useMemo(()=> _getPoolLength(), [_getPoolLength]);
    
        return { length }
    }
    
    export const getPoolLength = async () => {
       const poolLength = await masterchefV2Contract.poolLength();
       return poolLength.toNumber();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search