(
componentName: string,
id: string,
props: T,
options: {
logLevel?: 'debug' | 'info' | 'warn' | 'error'
enabled?: boolean
} = {},
)
| 109 | * } |
| 110 | */ |
| 111 | export function useWhyDidYouUpdateById<T extends Record<string, any>>( |
| 112 | componentName: string, |
| 113 | id: string, |
| 114 | props: T, |
| 115 | options: { |
| 116 | logLevel?: 'debug' | 'info' | 'warn' | 'error' |
| 117 | enabled?: boolean |
| 118 | } = {}, |
| 119 | ): void { |
| 120 | const env = getCliEnv() |
| 121 | const { logLevel = 'info', enabled = env.NODE_ENV === 'development' } = |
| 122 | options |
| 123 | |
| 124 | const previousProps = useRef<T | null>(null) |
| 125 | const renderCountById = useRef<Record<string, number>>({}) |
| 126 | |
| 127 | useEffect(() => { |
| 128 | if (!enabled) return |
| 129 | |
| 130 | renderCountById.current[id] = (renderCountById.current[id] || 0) + 1 |
| 131 | const renderCount = renderCountById.current[id] |
| 132 | |
| 133 | if (previousProps.current) { |
| 134 | const propKeys = Object.keys(props) as (keyof T)[] |
| 135 | const changedProps = propKeys.filter( |
| 136 | (key) => previousProps.current![key] !== props[key], |
| 137 | ) |
| 138 | |
| 139 | const logData = { |
| 140 | id, |
| 141 | renderCount, |
| 142 | changedProps: changedProps.map((key) => String(key)), |
| 143 | } |
| 144 | |
| 145 | if (changedProps.length > 0) { |
| 146 | logger[logLevel]( |
| 147 | { |
| 148 | ...logData, |
| 149 | propChanges: changedProps.reduce( |
| 150 | (acc, key) => { |
| 151 | acc[String(key)] = { |
| 152 | previous: previousProps.current![key], |
| 153 | current: props[key], |
| 154 | } |
| 155 | return acc |
| 156 | }, |
| 157 | {} as Record<string, { previous: any; current: any }>, |
| 158 | ), |
| 159 | }, |
| 160 | `${componentName} render #${renderCount} [${id}]: ${changedProps.length} ${changedProps.length === 1 ? 'prop' : 'props'} changed`, |
| 161 | ) |
| 162 | } else { |
| 163 | logger[logLevel]( |
| 164 | logData, |
| 165 | `${componentName} render #${renderCount} [${id}]: No props changed`, |
| 166 | ) |
| 167 | } |
| 168 | } else { |
no test coverage detected