i need to create a variable in a react-native component, which i want to use several times...each instance of this component needs to have a different variable name to reference to.
<View ref={view => { shapeView = view; }}
onLayout={({ nativeEvent }) => {
shapeView.measure( (x, y, width, height, pageX, pageY) => {
console.log('- - - DEBUG: width:' + width + ', pageX:'+ pageX + ', pageY:' + pageY);
let shapePickerPosition = {w: width, x: pageX, y: pageY};
setShapeCoords(shapePickerPosition);
})
}}>
as i said, i want to use this code inside a component, and this component several times, and if i don't change die variable: "shapeView" i end up with just the coordinates from the last instance of that component..
here's the whole component:
import React, {useState, useEffect} from 'react';
import {StyleSheet, View, Text, Modal, TouchableOpacity, Pressable, FlatList} from 'react-native';
import { useTheme} from '@react-navigation/native';
// ------------------PickerRow-----------------------------------------------------------------------
function CustomPickerRow(props) {
const { colors } = useTheme(); // works
const theme = useTheme();
const [selectedItem, setSelectedItem] = useState('choose');
const [coordinates, setCoordinates] = useState();
const setItem = (value) => {
// set parent state
props.action(value)
}
return (
<View
ref = { view => { shapeView = view; } }
onLayout={({ nativeEvent }) => {
shapeView.measure( (x, y, width, height, pageX, pageY) => {
console.log('height:', height);
console.log('width:', width);
console.log('x:', pageX);
console.log('y:', pageY);
let coords = {w: width, x: pageX, y: pageY};
setCoordinates(coords);
})
}}
style = {{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
height: 25,
paddingLeft: 5,
marginBottom: 3,
backgroundColor: colors.frameBackground,
borderColor: colors.borderColor,
borderWidth: 1,
borderRadius: 5}}>
<View style = {styles.icon} >
<Text style = {styles.text}>{props.icon}</Text>
</View>
<View style = {styles.description} >
<Text style = {{fontSize: 11, fontWeight: 'bold', color: colors.text, textAlign: 'left', marginLeft: 5,}}>{props.title}</Text>
</View>
<MyPicker data={props.data} action={setItem} position={coordinates}/>
</View>
);
}
// ------------------MyPicker-----------------------------------------------------------------------
function MyPicker(props) {
const { colors } = useTheme(); // works
const theme = useTheme();
const [isVisible, setIsVisible] = useState(false);
const [selectedItem, setSelectedItem] = useState(props.data[0].key)
const [coordinates, setCoordinates] = useState({w: 180, x: 0, y: 0});
useEffect(() => {
if (props.position) {
setCoordinates(props.position);
}
})
const setItem = item => {
// set parent state
props.action(item.value);
setIsVisible(false);
console.log("chosen value = " + item.key);
setSelectedItem(item.key);
}
const showPicker = () => {
setIsVisible(true);
}
const renderItem = ({item}) => {
return <View>
<Pressable onPress={() => setItem(item)}>
<Text style={{color: colors.text, fontSize: 17, alignSelf: 'center', paddingTop: 3}}>
{item.key}
</Text>
</Pressable>
</View>
}
return (
<View style={{flex:5, backgroundColor: 'transparent'}}>
<TouchableOpacity onPress={showPicker}>
<Text style={{color: colors.textSubtitleColor, fontSize: 11, alignSelf: 'flex-end', paddingRight: 10}}>
{selectedItem}
</Text>
</TouchableOpacity>
<Modal animationType="fade"
transparent={true}
visible={isVisible}
style={styles.testPicker}
onRequestClose={() => {
console.log('Modal has been closed.');
}}
>
<View style={{ backgroundColor: colors.frameBackground,
borderColor: colors.borderColor,
borderWidth: 1,
borderRadius: 5,
position: 'absolute',
width: 180,
height: 200,
left: coordinates.x, //100,
top: coordinates.y //160
}}>
<FlatList
data={props.data}
renderItem={renderItem}
/>
</View>
</Modal>
</View>
);
}
const styles = StyleSheet.create({
testPicker: {
backgroundColor: 'gray',
position: 'absolute',
width: 112,
height: 200,
left: 100,
top: 160
},
icon: {
flex: 1,
backgroundColor: '#00529F',
marginRight: 0,
borderRadius: 5
},
description: {
flex: 2,
height: 17,
backgroundColor: 'transparent',
marginRight: 0,
borderRadius: 5
},
});
export default CustomPickerRow;
and i call that component like this:
<CustomPickerRow id='shapePicker' icon='2' title='Shape:' data={shapeItems} action={setShape} selectedItem={selectedShape} visible={modalVisible} />```
shapeViewis outside your component to begin with (which I'll bet it is which is why you are trying to hack it). Post your full component code.shapeViewwhich results in the same behaviour as my SHOULD NOT be like this answer. Once you use a ref, it will work as expected.shapeViewis a global variable - every time a newCustomPickerViewgets rendered the single globalshapeViewvariable gets updated. What you need is ashapeViewreference per instance ofCustomPickerViewthat is on the screen. The way to do that is in the example I gave below. My initial assumption was right, and the first answer I gave you will solve your problem.