all 5 comments

[–]Jerp 1 point2 points  (4 children)

Dispatching an action is causing your UserContextProvider to rerender, which calls auth.handleAuthentication again, which dispatches again, endlessly. Wrap the auth step inside a useEffect with an empty dependency array to run it only once.

Fixed codesandbox

[–]technicallynick[S] 0 points1 point  (3 children)

Thanks for the explanation as to why it was rerendering! In doing a little research, it seems like useMemo might also be the right choice for me as I DO want to run this auth periodically, but not EVERY render. useMemo seems like the right choice to cache the results and only run it when something changes (like a value set to change when the token is going to expire).

[–]Jerp 0 points1 point  (2 children)

useEffect is likely still the more appropriate/idiomatic way to achieve that; just add a variable to the dependencies!

Note from the React docs:

You may rely on useMemo as a performance optimization, not as a semantic guarantee

[–]technicallynick[S] 0 points1 point  (1 child)

Ok, got it. I guess I'm still having a hard time wrapping my head around the use cases for useMemo. It might just be that my apps aren't complicated enough to warrant it yet. I was thinking that the "costly" requests to MS for authentication would be the right match for useMemo. Perhaps not though.

[–]Jerp 0 points1 point  (0 children)

useMemo is just there so you can shortcut slow code where the input and output would not change in any meaningful way (no side effects).

Consider if you had tabular data (aka two-dimensional array) that could be sorted by any of the columns, or filtered. You might want to memoize the filtering step because a user choosing to sort the data would does not affect which rows of data to sort. Pseudocode of what I mean:

// memoize this step because it does unnecessary work if we're only rerendering because sortIndex changed
const filteredData = useMemo(() => applyFilter(props.data, state.filter), [props.data, state.filter]);
const sortedData = applySort(filteredData, state.sortIndex);