Reputation: 658
I am following this tutorial
https://www.youtube.com/watch?v=ZiSN9uik6OY&list=RDCMUCTcH04SRuyedaSuuQVeAcdg&start_radio=1&t=1398
The problem is when I console.log( i.ref.current), I see all value. The ap will just not start with error Undefined is not an Object
inside the app.
and in reactive native console following comes up
This error is located at:
in Tabs (at App.js:118)
in RCTView (at View.js:34)
in View (at App.js:91)
in App (at renderApplication.js:47)
in RCTView (at View.js:34)
in View (at AppContainer.js:107)
in RCTView (at View.js:34)
in View (at AppContainer.js:134)
in AppContainer (at renderApplication.js:40)
ERROR TypeError: undefined is not an object (evaluating 'nativeNode._nativeTag')
below is the app.js file:
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, Dimensions, Animated, FlatList, Image } from 'react-native';
const {width, height} = Dimensions.get('screen')
const images = {
man:
'https://images.pexels.com/photos/3147528/pexels-photo-3147528.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500',
women:
'https://images.pexels.com/photos/2552130/pexels-photo-2552130.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500',
kids:
'https://images.pexels.com/photos/5080167/pexels-photo-5080167.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500',
skullcandy:
'https://images.pexels.com/photos/5602879/pexels-photo-5602879.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500',
help:
'https://images.pexels.com/photos/6857165/pexels-photo-6857165.jpeg?auto=compress&cs=tinysrgb&dpr=2&w=500',
};
const data = Object.keys(images).map((i) => ({
key: i,
title: i,
image: images[i],
ref: React.createRef()
}));
const Indicator = () =>{
return (<View style={{
position:'absolute',
height:4,
width:100,
backgroundColor:'white',
bottom: -10
}}/>);
}
const Tab = React.forwardRef(({item}, ref) => {
return (
<View ref={ref}>
<Text style={{
color:'rgba(255, 255, 255, 0.8)',
fontWeight:'800',
fontSize:84/data.length,
textTransform: 'uppercase' }}>{item.title}</Text>
</View>
);
});
const Tabs = ({data, scrollX}) =>{
const [measures, setMeasures] = React.useState([])
const containerRef = React.useRef();
React.useEffect(() => {
let m = []
data.forEach((i) => {
i.ref.current.measureLayout(
containerRef.current,
(x, y, width, height) => {
m.push({x, y, width, height})
console.log(x, y, width, height)
}
);
if(m.length === data.length){
setMeasures(m)
}
});
}, [])
console.log(measures);
return( <View style={{ position: 'absolute', top:50, width }}>
<View style={{justifyContent:'space-evenly', flex:1, flexDirection:'row'}}>
{
data.map((item) => {
return <Tab key={item.key} item={item} ref={item.ref} />
})
}
</View>
<Indicator/>
</View>
)
}
export default function App() {
const scrollX = React.useRef(new Animated.Value(0)).current;
return (
<View style={styles.container}>
<StatusBar hidden />
<Animated.FlatList
data={data}
keyExtractor={item => item.key}
renderItem={({item}) => {
return (<View style={{width, height}}>
<Image
source={{uri: item.image}}
style={{flex:1, resizeMode:'cover'}}
/>
<View style={
[
StyleSheet.absoluteFillObject,
{backgroundColor: 'rgba(0,0,0, 0.3)' }
]}/>
</View>)
}
}
horizontal
showsHorizontalScrollIndicator={false}
pagingEnabled
onScroll={Animated.event([{nativeEvent: {contentOffset :{x: scrollX } }}],
{useNativeDriver: false}
)}
bounces={false}
/>
<Tabs scrollX={scrollX} data={data} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
}); ```
Thanks. appreciate your time reading this
Upvotes: 2
Views: 7827
Reputation: 15722
The problem is that you haven't attached containerRef
to any View
.
Since the ref
isn't attached to a component containerRef.current
evaluates to undefined
, causing the logic in the useEffect
to break.
So your the Tabs
component should probably look more like this:
const Tabs = ({data, scrollX}) => {
const [measures, setMeasures] = React.useState([]);
const containerRef = React.useRef();
React.useEffect(() => {
let m = [];
data.forEach((i) => {
i.ref.current.measureLayout(
containerRef.current,
(x, y, width, height) => {
m.push({x, y, width, height});
console.log(x, y, width, height);
},
);
if (m.length === data.length) {
setMeasures(m);
}
});
}, []);
return (
<View style={{position: 'absolute', top: 50, width}}>
<View
ref={containerRef}
style={{justifyContent: 'space-evenly', flex: 1, flexDirection: 'row'}}>
{data.map((item) => {
return <Tab key={item.key} item={item} ref={item.ref} />;
})}
</View>
<Indicator />
</View>
);
};
Upvotes: 7