Add useStateCheckEquality, and use for user & contract hooks

This commit is contained in:
James Grugett 2022-04-06 13:55:59 -05:00
parent a2344492a2
commit 67d71fa531
3 changed files with 33 additions and 5 deletions

View File

@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { Contract, listenForContract } from '../lib/firebase/contracts'
import { useStateCheckEquality } from './use-state-check-equality'
export const useContract = (contractId: string) => {
const [contract, setContract] = useState<Contract | null | 'loading'>(
@ -14,12 +15,14 @@ export const useContract = (contractId: string) => {
}
export const useContractWithPreload = (initial: Contract | null) => {
const [contract, setContract] = useState<Contract | null>(initial)
const [contract, setContract] = useStateCheckEquality<Contract | null>(
initial
)
const contractId = initial?.id
useEffect(() => {
if (contractId) return listenForContract(contractId, setContract)
}, [contractId])
}, [contractId, setContract])
return contract
}

View File

@ -0,0 +1,21 @@
import _ from 'lodash'
import { useMemo, useRef, useState } from 'react'
export const useStateCheckEquality = <T>(initialState: T) => {
const [state, setState] = useState(initialState)
const stateRef = useRef(state)
stateRef.current = state
const checkSetState = useMemo(
() => (newState: T) => {
const state = stateRef.current
if (!_.isEqual(state, newState)) {
setState(newState)
}
},
[stateRef]
)
return [state, checkSetState] as const
}

View File

@ -1,3 +1,4 @@
import _ from 'lodash'
import { useEffect, useState } from 'react'
import { PrivateUser } from '../../common/user'
import {
@ -6,17 +7,20 @@ import {
listenForUser,
User,
} from '../lib/firebase/users'
import { useStateCheckEquality } from './use-state-check-equality'
export const useUser = () => {
const [user, setUser] = useState<User | null | undefined>(undefined)
const [user, setUser] = useStateCheckEquality<User | null | undefined>(
undefined
)
useEffect(() => listenForLogin(setUser), [])
useEffect(() => listenForLogin(setUser), [setUser])
const userId = user?.id
useEffect(() => {
if (userId) return listenForUser(userId, setUser)
}, [userId])
}, [userId, setUser])
return user
}