Unblock React Compiler for 6 components by removing render-phase ref access (#11544)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tomasz Zawadzki
2026-08-27 17:10:10 +02:00
committed by GitHub
parent b9bff931a3
commit f298a4ef5e
6 changed files with 27 additions and 41 deletions
@@ -270,10 +270,6 @@ function DialogInner({guide}: {guide?: Follow10ProgressGuide}) {
// Track seen profiles
const seenProfilesRef = useRef<Set<string>>(new Set())
const itemsRef = useRef(items)
itemsRef.current = items
const selectedInterestRef = useRef(selectedInterest)
selectedInterestRef.current = selectedInterest
const onViewableItemsChanged = useNonReactiveCallback(
({viewableItems}: {viewableItems: ViewToken[]}) => {
@@ -282,7 +278,7 @@ function DialogInner({guide}: {guide?: Follow10ProgressGuide}) {
if (item.type === 'profile') {
if (!seenProfilesRef.current.has(item.profile.did)) {
seenProfilesRef.current.add(item.profile.did)
const position = itemsRef.current.findIndex(
const position = items.findIndex(
i => i.type === 'profile' && i.profile.did === item.profile.did,
)
ax.metric('suggestedUser:seen', {
@@ -292,9 +288,7 @@ function DialogInner({guide}: {guide?: Follow10ProgressGuide}) {
position: position !== -1 ? position : 0,
suggestedDid: item.profile.did,
category:
selectedInterestRef.current === FOR_YOU_TAB
? null
: selectedInterestRef.current,
selectedInterest === FOR_YOU_TAB ? null : selectedInterest,
})
}
}
+5 -16
View File
@@ -1,11 +1,5 @@
import {Fragment, useMemo, useRef} from 'react'
import {
Keyboard,
Platform,
type StyleProp,
View,
type ViewStyle,
} from 'react-native'
import {Keyboard, type StyleProp, View, type ViewStyle} from 'react-native'
import {AtUri} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -32,7 +26,7 @@ import {Group3_Stroke2_Corner0_Rounded as GroupIcon} from '#/components/icons/Gr
import {InlineLinkText} from '#/components/Link'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_NATIVE} from '#/env'
import {IS_NATIVE, IS_WEB} from '#/env'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
@@ -110,14 +104,9 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) {
}
onPress={onPressOpen}
{...(isThreadAuthor
? Platform.select({
web: {
onHoverIn: prefetch,
},
native: {
onPressIn: prefetch,
},
})
? IS_WEB
? {onHoverIn: prefetch}
: {onPressIn: prefetch}
: {})}
hitSlop={HITSLOP_10}>
{({hovered, focused, pressed}) => (
@@ -9,7 +9,7 @@ import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {mergeRefs} from '#/lib/merge-refs'
import {atoms as a, ios, platform, useTheme} from '#/alf'
import {atoms as a, platform, useTheme} from '#/alf'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {Text} from '#/components/Typography'
import {IS_ANDROID, IS_IOS} from '#/env'
@@ -94,7 +94,11 @@ export function OTPInput({
</View>
<TextInput
// SMS autofill is borked on iOS if you open the keyboard immediately -sfn
onLayout={ios(() => setTimeout(() => innerRef.current?.focus(), 100))}
onLayout={
IS_IOS
? () => setTimeout(() => innerRef.current?.focus(), 100)
: undefined
}
autoFocus={IS_ANDROID}
accessible
accessibilityLabel={label}
+8 -8
View File
@@ -1,12 +1,12 @@
import {useRef} from 'react'
import {useState} from 'react'
import {Animated} from 'react-native'
export function useAnimatedValue(initialValue: number) {
const lazyRef = useRef<Animated.Value>(undefined)
if (lazyRef.current === undefined) {
lazyRef.current = new Animated.Value(initialValue)
}
return lazyRef.current
/*
* A lazy `useState` initialiser rather than a lazily-populated ref: both
* construct once and keep the same instance, but reading a ref during render
* is a Rules of React violation.
*/
const [value] = useState(() => new Animated.Value(initialValue))
return value
}
+3 -3
View File
@@ -1,4 +1,4 @@
import {useEffect, useRef, useState} from 'react'
import {useEffect, useState} from 'react'
import {AppState, type AppStateStatus} from 'react-native'
import {createAsyncStoragePersister} from '@tanstack/query-async-storage-persister'
import {
@@ -168,8 +168,8 @@ function QueryProviderInner({
children: React.ReactNode
currentDid: string | undefined
}) {
const initialDid = useRef(currentDid)
if (currentDid !== initialDid.current) {
const [initialDid] = useState(currentDid)
if (currentDid !== initialDid) {
throw Error(
'Something is very wrong. Expected did to be stable due to key above.',
)
+3 -4
View File
@@ -2,9 +2,9 @@ import {
createContext,
useContext,
useEffect,
useEffectEvent,
useMemo,
useReducer,
useRef,
} from 'react'
import {useCurrentConvoId} from './current-convo-id'
@@ -44,8 +44,7 @@ export function useMessageDraft() {
export function useSaveMessageDraft(message: string) {
const {currentConvoId} = useCurrentConvoId()
const {dispatch} = useMessageDraftsContext()
const messageRef = useRef(message)
messageRef.current = message
const getMessage = useEffectEvent(() => message)
useEffect(() => {
return () => {
@@ -53,7 +52,7 @@ export function useSaveMessageDraft(message: string) {
dispatch({
type: 'set',
convoId: currentConvoId,
draft: messageRef.current,
draft: getMessage(),
})
}
}