router icon indicating copy to clipboard operation
router copied to clipboard

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()

Open rakeshpetit opened this issue 2 years ago • 10 comments

Summary

 ERROR  Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `SlotClone`.
    in Button (created by SlotClone)
    in SlotClone (created by Slot)
    in Slot
    in ExpoRouterLink (created by Home)
    in RCTView (created by View)
    in View
    in NativeWind.View
    in Unknown (created by Home)
    in RCTView (created by View)
    in View
    in NativeWind.View
    in Unknown (created by Screen)
    in Screen (created by Home)
    in RNCSafeAreaView
    in Unknown
    in NativeWind.NoName
    in Unknown (created by SafeArea)
    in SafeArea (created by Home)
    in Home (created by Route(Home))
    in Route (created by Route(Home))
    in LocationProvider (created by Route(Home))
    in Route(Home) (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by QualifiedSlot)
    in QualifiedSlot (created by Slot)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by QualifiedNavigator)
    in QualifiedNavigator (created by Navigator)
    in Navigator (created by Slot)
    in Slot (created by RootLayout)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by RootLayout)
    in Provider (created by RootLayout)
    in RootLayout (created by Route(RootLayout))
    in Route (created by Route(RootLayout))
    in LocationProvider (created by Route(RootLayout))
    in Route(RootLayout) (created by RootRoute)
    in RootRoute (created by ContextNavigator)
    in LocationProvider (created by ContextNavigator)
    in InitialRootStateProvider (created by ContextNavigator)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by InternalContextNavigationContainer)
    in InternalContextNavigationContainer (created by ContextNavigationContainer)
    in ContextNavigationContainer (created by ContextNavigator)
    in RootRouteNodeProvider (created by ContextNavigator)
    in ContextNavigator (created by ExpoRoot)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by ExpoRoot)
    in ExpoRoot (created by App)
    in App (created by ErrorOverlay)
    in ErrorToastContainer (created by ErrorOverlay)
    in ErrorOverlay (created by withDevTools(ErrorOverlay))
    in withDevTools(ErrorOverlay)
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in main(RootComponent)

We receive an Yellow screen warning with the error mentioned above with example 1 whereas it works fine for example 2.

Minimal reproducible example

Example 1

import { Link } from 'expo-router'
import { StatusBar } from 'expo-status-bar'
import { Text, View } from 'react-native'

const MyLink = () => {
  return <Text>Button</Text>
}

export default function Home() {
  return (
    <View>
      <StatusBar style="auto" />
      <Link href="/route" asChild>
        <MyLink />
      </Link>
    </View>
  )
}

Example 2

import { Link } from 'expo-router'
import { StatusBar } from 'expo-status-bar'
import { Text, View } from 'react-native'

export default function Home() {
  return (
    <View>
      <StatusBar style="auto" />
      <Link href="/route" asChild>
        <Text>Button</Text>
      </Link>
    </View>
  )
}

rakeshpetit avatar Feb 13 '23 13:02 rakeshpetit

get the same error when using expo-router with react-native-paper. Here is the example:

import { Link } from 'expo-router';
import { Button, Text } from 'react-native-paper';

export default function Comp() {
  return (
        <Link href="/" asChild>
          <Button mode="contained-tonal">
            <Text>Semua</Text>
          </Button>
        </Link>
    />
  );
}

cholazzzb avatar May 12 '23 06:05 cholazzzb

I think the child component needs forwardRef:

import { forwardRef } from 'react'
import { Pressable as RNPressable } from 'react-native'

const Pressable = forwardRef(({ children, ...props }, ref) => {
  return <RNPressable ref={ref} {...props}>{children}</RNPressable>
})

export default Pressable

thame avatar Jul 06 '23 18:07 thame

get the same error when using expo-router with react-native-paper. Here is the example:

import { Link } from 'expo-router';
import { Button, Text } from 'react-native-paper';

export default function Comp() {
  return (
        <Link href="/" asChild>
          <Button mode="contained-tonal">
            <Text>Semua</Text>
          </Button>
        </Link>
    />
  );
}

Did you ever find a fix?

balloman avatar Jul 15 '23 20:07 balloman

get the same error when using expo-router with react-native-paper. Here is the example:

import { Link } from 'expo-router';
import { Button, Text } from 'react-native-paper';

export default function Comp() {
  return (
        <Link href="/" asChild>
          <Button mode="contained-tonal">
            <Text>Semua</Text>
          </Button>
        </Link>
    />
  );
}

Did you ever find a fix?

I think "react-native-paper" Button cant not receive ref (don't wrapping with React.forwardRef) react native paper's Button

Kwonkunkun avatar Jul 18 '23 05:07 Kwonkunkun

@rakeshpetit

You use custom component <MyLink/> without React.forwardRef in first example. (functional component must wrap React.forwardref, if you want pass ref.)

and Text component maybe built in Class component or use React.forwardRef.

so, you must wrap your custom component to"forwardRef" , if you want to pass ref

Kwonkunkun avatar Jul 18 '23 05:07 Kwonkunkun

I also had this problem. My adapted component looks like this:

import React from "react";
import {
  GestureResponderEvent,
  Pressable,
  StyleSheet,
  Text,
  View,
  useColorScheme,
} from "react-native";

import generalStyles from "../../styles/general";
import { COLORS, Theme } from "../../styles/theme.style";

interface IButton {
  onPress: (event: GestureResponderEvent) => void;
  onClick?: (event: GestureResponderEvent) => void;
  title: string;
  style?: Record<string, unknown>;
  textStyle?: Record<string, unknown>;
}

const CustomButton = React.forwardRef<View, IButton>((props, ref) => {
  const { title = "Enter", style = {}, textStyle = {}, onPress } = props;

  const theme = Theme[useColorScheme() === "dark" ? "dark" : "light"];
  return (
    <Pressable
      ref={ref}
      onPress={onPress}
      style={({ pressed }) => [
        styles.button,
        pressed ? theme.button.pressed : theme.button,
        generalStyles.button,
        theme.button,
        style,
      ]}
    >
      <Text
        style={[
          { color: COLORS.white },
          generalStyles.text,
          styles.text,
          textStyle,
        ]}
      >
        {title}
      </Text>
    </Pressable>
  );
});

CustomButton.displayName = "CustomButton";

export default CustomButton;

const styles = StyleSheet.create({
  button: {
    display: "flex",
    borderRadius: 5,
    justifyContent: "center",
    alignItems: "center",
  },
  text: {
    padding: 3,
  },
});

tickietackie avatar Jul 28 '23 17:07 tickietackie

FYI, for anyone running into this issue using the core React Native Button component, they merged a fix a few months back that was recently made available in 0.76.0-rc.0.

h14h avatar Sep 11 '24 22:09 h14h

I have a similar issue here. It only happens with asChild (which creates the Slot which probably doesn't like something).

bhabegger avatar Jan 08 '25 13:01 bhabegger

same problem for me

I have a similar issue here. It only happens with asChild (which creates the Slot which probably doesn't like something).

dadebue avatar Jan 08 '25 13:01 dadebue

same problem for me

I have a similar issue here. It only happens with asChild (which creates the Slot which probably doesn't like something).

I just ran into this as well whenever I use a <Pressable /> or <TouchableOpacity />

bubbomb avatar Jan 23 '25 00:01 bubbomb