简体   繁体   English

React Native-在按下按钮时打开选择器

[英]React Native - Open Picker on Button Press

I am using react-native-simple-picker in my app which works fine in my project if I use the default show button but I would like to show the picker when I use a different button in my project. 我在我的应用程序中使用react-native-simple-picker,如果我使用默认的显示按钮,则在我的项目中效果很好,但是当我在项目中使用其他按钮时,我想显示选择器。 It looks like this.refs.picker.show() in ProposalPicker.js is the function that needs to be called, but I am not sure how to access this from another component file. 看起来像this.refs.picker.show()是需要调用的函数,但是我不确定如何从另一个组件文件访问它。 Currently my code results in the following error - `Cannot read property 'show' of undefined. 目前,我的代码导致以下错误-无法读取未定义的属性“ show”。 Appreciate any help. 感谢任何帮助。

ProposalPicker.js ProposalPicker.js

import React, { Component } from 'react';
import { Picker, View, Text } from 'react-native';
import Button from './Button';
import SimplePicker from 'react-native-simple-picker';


const options = ['Option1', 'Option2', 'Option3'];

// Labels is optional
const labels = ['Banana', 'Apple', 'Pear'];

class ProposalPicker extends Component {
    constructor(props) {
      super(props);

      this.state = {
        selectedOption: '',
      };
    }

    render() {
      return (
        <View style={styles.container}>
          <Text style={styles.paragraph}>Current Option: {this.state.selectedOption}</Text>

          <Text
            style={{ color: '#006381', marginTop: 20 }}
            onPress={() => {
              this.refs.picker.show();
            }}
          >
              Click here to select your option
          </Text>

          <Text
            style={{ color: '#006381', marginTop: 20 }}
            onPress={() => {
              this.refs.picker2.show();
            }}
          >
              Click here to select your option with labels
          </Text>

          <SimplePicker
            ref={'picker'}
            options={options}
            onSubmit={(option) => {
              this.setState({
                selectedOption: option,
              });
            }}
          />

          <SimplePicker
            ref={'picker2'}
            options={options}
            labels={labels}
            itemStyle={{
              fontSize: 25,
              color: 'red',
              textAlign: 'left',
              fontWeight: 'bold',
            }}
            onSubmit={(option) => {
              this.setState({
                selectedOption: option,
              });
            }}
          />
        </View>
      );
    }
  }

// class ProposalPicker extends Component {
//     state={proposal: ''}
//     selectedValue = '';
//     updateProposal = (proposal) => {
//         this.setState({ proposal: this.selectedValue });
//     }
//     handleConfirmClick = () => {
//         this.setState({ proposal: this.selectedValue });
//     }
//     render() {
//         return (


//                 <View>
//                     <Picker selectedValue = {this.selectedValue} 
//                             onValueChange = {this.updateProposal}
//                             itemStyle={{ backgroundColor: 'grey' }}

//                     >


//                         <Picker.Item label = "Test" value = "TestValue1" />
//                         <Picker.Item label = "Test 1" value = "TestValue2" />
//                         <Picker.Item label = "Test" value = "TestValue3" />
//                         <Picker.Item label = "Test" value = "TestValue4" />
//                         <Picker.Item label = "Test" value = "TestValue5" />
//                         <Picker.Item label = "Test" value = "TestValue6" />
//                         <Picker.Item label = "Test" value = "TestValue7" />
//                         <Picker.Item label = "Test" value = "TestValue8" />
//                         <Picker.Item label = "Test nothing" value = "TestValue9" />


//                     </Picker>

//                     <Text style = {styles.textStyle}>CONFIRM</Text>





//                 </View>


//         )
//     }
// }



const styles = {
    proposalPickerStyle: {
        backgroundColor: 'lightgrey'
    },
    textStyle: {
        flex: 1
    }
}

export default ProposalPicker;

ProposalPickerButton.js ProposalPickerButton.js

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

const PickerButton = ({ onPress, text }) => {
    const { textStyle, iconStyle, iconContainerStyle, textContainerStyle, buttonStyle } = styles;
    return (

       <TouchableOpacity onPress={onPress} style={buttonStyle}>
        <View style={styles.containerStyle}>
            <View style={iconContainerStyle}>
                <Image
                    style={iconStyle}
                    source={require('./images/201.png')}

                />

                </View>

                <View style={textContainerStyle}>
                    <Text style={textStyle}>{text}</Text>
                </View>

                <View style={iconContainerStyle}>
                    <Image
                    style={iconStyle}
                        source={require('./images/201.png')}
                />
            </View>
        </View>
        </TouchableOpacity>
    );
}

const styles = {
    containerStyle: {
        flex: 1,
        //backgroundColor: 'red',
        borderWidth: 2,
        borderRadius: 0,
        borderColor: '#FFFFFF',
        //shadowColor: '#000',
        //shadowOffset: { width: 0, height: 2 },
        //shadowOpacity: 0.1,
        //shadowRadius: 2,
        //elevation: 1,
        marginLeft: 40,
        marginRight: 40,
        marginTop: 10,
        marginBottom: 10,
        justifyContent: 'center',
        alignItems: 'center',
        flexDirection: 'row'

    },
    iconContainerStyle: {
        flex: 2,
        //backgroundColor: 'blue',
        justifyContent: 'center',
        //alignItems: 'center',
        //width: '20%',
        //height: '20%'

    },
    iconStyle: {
        flex: 1,
        width: null,
        height: null,
        resizeMode: 'contain',
        marginLeft: 10,
        marginRight: 10,
        marginTop: 10,
        marginBottom: 10
    },
    textContainerStyle: {
        flex: 8,
        //backgroundColor: 'orange',
        alignItems: 'flex-start',
        justifyContent: 'center',
    },
    textStyle: {

        fontSize: 20,
        fontWeight: 'bold',
        color: '#FFFFFF',
        //marginLeft: 10

        //padding: 18
    },
    buttonStyle: {
        width: '100%',
        height: '100%'
    }
};

export default PickerButton;

App.js App.js

import React, { Component } from 'react';
import { View, Text, ImageBackground } from 'react-native';
import Logo from './Logo';
import ProposalPickerButton from './ProposalPickerButton';
import Button from './Button';
import ProposalPicker from './ProposalPicker';
import SimplePicker from 'react-native-simple-picker';

class App extends Component {

    render() {
        return (

                <ImageBackground
                    source={require('./images/city.png')}
                    style={styles.backgroundStyle}
                >

                    <View style={styles.backgroundOverlayStyle} />

                        <View style={styles.container}>

                            <View style={styles.logoContainer}>

                                <Logo />
                            </View>

                            <View style={styles.proposalPickerButtonStyle}>

                                    <ProposalPickerButton
                                        onPress={() => new ProposalPicker().refs.picker.show()}
                                        // onPress={() => console.log('Proposal picker button pressed')}
                                        //onPress={() => Linking.openURL(url)}
                                        text="Select a service line" 
                                    />

                            </View>

                            <View style={styles.startProposalButtonStyle}>
                                <Button text="Start proposal"/>
                            </View>


                            <View style={styles.proposalPickerStyle}>

                              {/* <ProposalPicker /> */}

                            </View>

                        </View>

                </ImageBackground>
        );
    }
}

const styles = {

    backgroundStyle: {
        flex: 1,
        backgroundColor: '#000000',
        width: '100%',
        height: '100%',
        position: 'absolute'
    },
    backgroundOverlayStyle: {
        flex: 1,
        position: 'absolute',
        backgroundColor: '#003284',
        opacity: 0.5,
        width: '100%',
        height: '100%'

    },
    container: {
        //backgroundColor: 'red',
        flex: 1,
        //opacity: 0.5,
        alignItems: 'center',
        width: '100%',
        height: '65%',
    },
    logoContainer: {
        //backgroundColor: 'blue',
        flex: 3,
        alignItems: 'center',
        justifyContent: 'center',
        width: '100%',
        height: '65%',
    },
    proposalPickerButtonStyle: {
        flex: 1,
        //backgroundColor: 'yellow',
        alignItems: 'center',
        justifyContent: 'center',
        width: '100%',
        height: '100%',
        marginLeft: 100,
        marginRight: 100
    },
    startProposalButtonStyle: {
        flex: 1,
        //backgroundColor: 'purple',
        width: '100%',
        height: '100%',
        marginTop: 10,
        marginRight: 80
    },
    proposalPickerStyle: {
        opacity: 1,
        flex: 2,
        backgroundColor: 'green',
        width: '100%',
        height: '100%'
    },



};

export default App;

To call methods via refs you need to have a ref assigned to an already mounted component. 要通过引用调用方法,您需要将引用分配给已安装的组件。 Therefore you can't say new ProposalPicker().refs.picker.show() because refs.picker does not exist until the component is mounted. 因此,您不能说new ProposalPicker().refs.picker.show()因为在安装组件之前refs.picker不存在。 You Should have your button and picker components in the same parent, that way you can easily create a ref in that parent, assign it, and call methods from it: 您应该将按钮和选择器组件放在同一个父级中,这样,您就可以轻松地在该父级中创建引用,对其进行分配并从中调用方法:

Also you should use callback refs instead of string refs because string refs are deprecated. 同样,您应该使用回调ref而不是字符串ref,因为不推荐使用字符串ref。 In that case it would look like: 在这种情况下,它看起来像:

constructor(props){
  super(props)
  this.state = ...

  this.picker = React.createRef() // make the ref
}

Then assign the ref: 然后分配参考:

<SimplePicker
  ref={this.picker}

And then you can make an function to call when your button is pressed: 然后,您可以使函数在按下按钮时调用:

showPicker = () => {
  if (this.picker.current) {
    this.picker.current.show()
  }
}

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

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