Home > OS >  Function components can not be given refs. Attempts to access this ref will fail
Function components can not be given refs. Attempts to access this ref will fail

Time:01-18

Console 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 'OnboardingScreen' Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?%s%S Check the render method of 'OnboardingScreen*

I get this warning and I can't transmit Ref

OnboardingScreen

import React, {useRef, useState} from 'react';
import {Dimensions, View} from 'react-native';
import {ONBOARDING} from '../data/onboarding';
import Onboarding from '../components/ Onboarding/Onboarding';
import OnboardingFooter from '../components/ Onboarding/OnboardingFooter';
import {colors} from '../constants/config';

const windowWidth = Dimensions.get('window').width;
const OnboardingScreen = () => {
  const [currentSate, setCurrentState] = useState(0);
  const ref = useRef(null);
  const updateCurrentState = e => {
    const contentOffsetX = e.nativeEvent.contentOffset.x;
    const currentSate = Math.round(contentOffsetX / windowWidth);
    setCurrentState(currentSate);
  };
  const nextSlider = () => {
    const nextSliderState = currentSate   1;
    if (nextSliderState != ONBOARDING.length) {
      const offset = nextSliderState * windowWidth;
      ref?.current?.scrollToOffset({offset});
      setCurrentState(nextSliderState);
    }
  };
  return (
    <View style={{flex: 1, backgroundColor: colors.lightGray}}>
      <Onboarding
        list={ONBOARDING}
        updateCurrentState={updateCurrentState}
        ref={ref}
      />
      <OnboardingFooter
        list={ONBOARDING}
        currentSate={currentSate}
        nextSlider={nextSlider}
      />
    </View>
  );
};

export default OnboardingScreen;

Onboarding

import React from 'react';
import {Dimensions, FlatList, Image, Text, View} from 'react-native';

const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const Onboarding = ({list, updateCurrentState, ref}) => {
  return (
    <FlatList
      data={list}
      horizontal
      ref={ref}
      pagingEnabled
      onMomentumScrollEnd={updateCurrentState}
      contentContainerStyle={{height: windowHeight * 0.75}}
      showsHorizontalScrollIndicator={false}
      renderItem={({item, index}) => {
        return (
          <View style={{alignItems: 'center'}}>
            <Image
              source={item.image}
              style={{height: '75%', width: windowWidth}}
            />
            <Text
              style={{
                color: 'white',
                fontSize: 22,
                fontWeight: 'bold',
                marginTop: 30,
              }}>
              {item.title}
            </Text>
            <Text
              style={{
                color: 'white',
                fontSize: 13,
                marginTop: 5,
                maxWidth: '80%',
                textAlign: 'center',
                lineHeight: 23,
              }}>
              {item.subtitle}
            </Text>
          </View>
        );
      }}
    />
  );
};

export default Onboarding;


CodePudding user response:

You need to follow forwarding ref concept, refer to this doc: https://reactjs.org/docs/forwarding-refs.html

Your solution is as below:

import React, {useRef, useState} from 'react';
import {Dimensions, View} from 'react-native';
import {ONBOARDING} from '../data/onboarding';
import Onboarding from '../components/ Onboarding/Onboarding';
import OnboardingFooter from '../components/ Onboarding/OnboardingFooter';
import {colors} from '../constants/config';

const windowWidth = Dimensions.get('window').width;
const OnboardingScreen = () => {
  const [currentSate, setCurrentState] = useState(0);

  const ref = React.createRef(null); //<-----------change here

  const updateCurrentState = e => {
    const contentOffsetX = e.nativeEvent.contentOffset.x;
    const currentSate = Math.round(contentOffsetX / windowWidth);
    setCurrentState(currentSate);
  };
  const nextSlider = () => {
    const nextSliderState = currentSate   1;
    if (nextSliderState != ONBOARDING.length) {
      const offset = nextSliderState * windowWidth;
      ref?.current?.scrollToOffset({offset});
      setCurrentState(nextSliderState);
    }
  };
  return (
    <View style={{flex: 1, backgroundColor: colors.lightGray}}>
      <Onboarding
        list={ONBOARDING}
        updateCurrentState={updateCurrentState}
        ref={ref}
      />
      <OnboardingFooter
        list={ONBOARDING}
        currentSate={currentSate}
        nextSlider={nextSlider}
      />
    </View>
  );
};

export default OnboardingScreen;

Onboarding

import React from 'react';
import {Dimensions, FlatList, Image, Text, View} from 'react-native';

const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
const Onboarding = React.forwardRef(({list, updateCurrentState},ref) => {   //<====================here
  return (
    <FlatList
      data={list}
      horizontal
      ref={ref}
      pagingEnabled
      onMomentumScrollEnd={updateCurrentState}
      contentContainerStyle={{height: windowHeight * 0.75}}
      showsHorizontalScrollIndicator={false}
      renderItem={({item, index}) => {
        return (
          <View style={{alignItems: 'center'}}>
            <Image
              source={item.image}
              style={{height: '75%', width: windowWidth}}
            />
            <Text
              style={{
                color: 'white',
                fontSize: 22,
                fontWeight: 'bold',
                marginTop: 30,
              }}>
              {item.title}
            </Text>
            <Text
              style={{
                color: 'white',
                fontSize: 13,
                marginTop: 5,
                maxWidth: '80%',
                textAlign: 'center',
                lineHeight: 23,
              }}>
              {item.subtitle}
            </Text>
          </View>
        );
      }}
    />
  );
});       //<============here

export default Onboarding;
  • Related