简体   繁体   English

在 react-native 组件中动态创建变量

[英]create variable dynamically in react-native component

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.我需要在 react-native 组件中创建一个变量,我想多次使用它……这个组件的每个实例都需要有一个不同的变量名来引用。

<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..正如我所说,我想在一个组件中多次使用此代码,并且多次使用此代码,如果我不更改 die 变量:“shapeView”,我最终只会得到该组件最后一个实例的坐标。

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} />```

shapeView should be a ref like this: shapeView应该是这样的参考:

const MyComponent = () => {
   const shapeView = useRef();

   return (
     <View
       ref={view => shapeView.current = view}
       /* could also look like this: ref={shapeView} */
       onLayout={({nativeEvent}) => {
          shapeView.current.measure(...);
       }
     />
   )
}

It SHOULD NOT be like this:应该是这样的:

let shapeView; // this is outside your component - it shouldn't be here
const MyComponent = () => {

   return (
     <View
       ref={view => shapeView = view}
       onLayout={({nativeEvent}) => {
          shapeView.measure(...);
       }
     />
   )
}

In a class based component it could look like this:在基于类的组件中,它可能如下所示:


class MyComponent extends React.Component {

    constructor() {
       this.shapeView = React.createRef();
    }

    render() {
       return (
         <View
           ref={this.shapeView}
           onLayout={({nativeEvent}) => {
              this.shapeView.current.measure(...);
           }
         />
       )
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM