Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Flatlist createRef().current is null when opening sidemenu

I’m using React Native and have built an autoscrolling Flatlist using the component ref to access the scrollToIndex method.

All works fine, until I open the SideMenu which somehow causes flatList.current to become null, causing an application error.

I wonder if anyone know why this is occuring? Appreciate the help.
Thanks

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

App.js

import React, {useState} from 'react';
import { StyleSheet, Text, Image, View, SafeAreaView, ScrollView } from 'react-native';
import Background from './components/Background'
import Header from './components/Header'
import SideMenu from './components/SideMenu';
import SearchBar from './components/SearchBar'
import Swiper from './components/Swiper'

export default function App() {

const [ sideMenuOpen, setSideMenuOpen ] = useState(false)

const hamburgerHandler = () => {

  sideMenuOpen ? setSideMenuOpen(false) : setSideMenuOpen(true)

}

return (
  <SafeAreaView style={styles.container}>
    <View style={styles.background}>
      <Background />
    </View>
    <Header sideMenuOpen={sideMenuOpen} setSideMenu={hamburgerHandler} />
    <SideMenu sideMenuOpen={sideMenuOpen} />
    <SearchBar />
    <View style={sideMenuOpen ? styles.contentContainer : {height: '100%'}} >
      <ScrollView>          
        <Swiper header={'Movies & TV: Coming Soon'} interval={6000} />
      </ScrollView>      
    </View>
  </SafeAreaView>
  );
}

Swiper.js

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

const Slider = props => {

  const flatList = createRef()
  const renderItem = ({ item }) => <Item content={item} />
  const header = props.header ? <Text style={styles.header}>{props.header}</Text> : <Text> 
  </Text>

  let currentSlide = 0
  let timer

  const _incrementSlider = (scale=0) => {
    currentSlide+=scale
    if (currentSlide > data.length-1) currentSlide = 0

    flatList.current.scrollToIndex({
      index: currentSlide,
      animated: true
    })
  }

  const _startAutoPlay = () => {
    if (!props.interval) return
    timer = setInterval(() => _incrementSlider(1), props.interval)
  }

  const _stopAutoPlay = () => {
    clearInterval(timer)
    timer = null
  }

  //ComponentDidMount
  useEffect(() => {
    console.log('mounted')
    _startAutoPlay()
  }, [])

  //ComponentWillUnmount
  useEffect(() => {
    return () => {
      console.log('unmounted')
      _stopAutoPlay()
    }
  }, [])

  return (
    <View style={styles.container}>
      {header}
      <FlatList
        data={data}
        pagingEnabled={true}
        horizontal={true}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        ref={flatList}
      />
    </View>
  )

}

>Solution :

Every time this component renders, you call createRef again, which creates a brand new ref. As a new ref, it has null for its .current property. createRef is not really meant for use in function components, and instead you should use useRef. It will create the ref just once, and return it to you on every render.

import React, { useEffect, useRef } from "react";
// ...
const flatList = useRef();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading