Purushotham Kumar
Purushotham Kumar

Reputation: 245

Unable to render a view onPress TouchableOpacity in react native

I want to render a view on press a TouchableOpacity but it is not working. Can any please suggest the best solution?

import React, { Component } from 'react';
import {
    AppRegistry,
    View,
    TouchableOpacity
} from 'react-native';

export default class App extends Component {
   
    constructor(props){
        super(props);
        this._renderMyView.bind(this);
    }

    _renderMyView = () => {
      <View>
          <Text>I am here to returns camera</Text>
          <Text>I am here to returns camera</Text>
          <Text>I am here to returns camera</Text>
          <Text>I am here to returns camera</Text>
          <Text>I am here to returns camera</Text>
          <Text>I am here to returns camera</Text>
          <Text>I am here to returns camera</Text>
          <Text>I am here to returns camera</Text>
      </View>
    }

    render() {
        return (
       
                <TouchableOpacity  onPress={this._renderMyView} style={{height:50,width:50,backgroundColor:'red'}} >
                    <Text style={{height:50,width:50,backgroundColor:'red'}} >camera</Text>
                </TouchableOpacity>

        );
    }
}

Upvotes: 4

Views: 3248

Answers (3)

Yossi
Yossi

Reputation: 445

For now, there is no indication that your component can depend on when it should render your view. It can simply solve by:

  1. Add state to component, for example: state = { renderView : false }

  2. add conditionally render, depends on your state:

    render() {
        return (
            <TouchableOpacity onPress={this._renderMyView} style={{height: 50, width: 50, backgroundColor: 'red'}}>
                <Text style={{height: 50, width: 50, backgroundColor: 'red'}}>camera</Text>
                {this.state.renderView && this._renderMyView()}
            </TouchableOpacity>
        )}
    
  3. return your view from _renderMyView(), so just add return statement for your view.

  4. change state when press triggered: <TouchableOpacity onPress={() => this.setState({renderView: true})} ... >

Upvotes: 1

Facundo La Rocca
Facundo La Rocca

Reputation: 3866

The way React works is based on state changes, so you always render based on the current state (or props). If you need to render based on some changes, then you should first alter the state and later render conditionally to the new state:

import React, { Component } from 'react';
import {
    AppRegistry,
    View,
    TouchableOpacity
} from 'react-native';

export default class App extends Component {

    constructor(props){
        super(props);

        this.state = {
            renderView: false
        }

        //You had a slighty mistake here, you have to assign bind's result
        this._renderMyView = this._renderMyView.bind(this);
        this._onPress= this._onPress.bind(this);
    }

    render() {
        return (
            <View style={{flex: 1}}>
                {this._renderMyView()}
                <TouchableOpacity  onPress={this._onPress} style={{height:50,width:50,backgroundColor:'red'}} >
                    <Text style={{height:50,width:50,backgroundColor:'red'}} >camera</Text>
                </TouchableOpacity>
            </View>
        );
    }

    _onPress() {
       //React to the event and change the state
       this.setState({renderView: true});
   }

    _renderMyView () {
        //Render based on the current state
        if(this.state.renderView) {
            return (
              <View>
                  <Text>I am here to returns camera</Text>
                  <Text>More stuff here...</Text>
              </View>
            );
        }

        return null;
    }
}

In order to clarify, each time that this.setState is called, the component's cycle life is executed, for more information refer to the oficial docs, update section. That is to say:

  1. componentWillReceiveProps()
  2. shouldComponentUpdate()
  3. componentWillUpdate()
  4. render()
  5. componentDidUpdate()

As an additional comment (for the sake of the example above it is not required), this.setState executes asynchronously, that means that in case you need to do something immediately after the state is modified, you must pass a callback as a second parameter:

this.setState({someProp: 1}, () => {
    console.log('someProp: ' + this.state.someProp); //someProp: 1
});

Doing this will produce unexpected behavior:

this.setState({someProp: 1});
//You cannot ensure that the state has changed at this point, so the following line could be the expected or the previous value
console.log('someProp: ' + this.state.someProp); //someProp: ???

Upvotes: 1

sumesh
sumesh

Reputation: 2249

you should return the JSX like this. Also give flex 1 to view

import React, { Component } from 'react';


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

export default class App extends Component {

constructor(props){
    super(props);
    this.state = {
      visible: false,
    }
}

_renderMyView = () => {
  return (
    <View style={{height: 50, backgroundColor: '#eee',marginTop: 100}}>
        <Text>I am here to returns camera</Text>
        <Text>I am here to returns camera</Text>
        <Text>I am here to returns camera</Text>
        <Text>I am here to returns camera</Text>
        <Text>I am here to returns camera</Text>
        <Text>I am here to returns camera</Text>
        <Text>I am here to returns camera</Text>
        <Text>I am here to returns camera</Text>
    </View>
  );

}

render() {
    return (

            <View style={{flex: 1}}>
              <TouchableOpacity  onPress={()=>{this.setState({visible: true})}} style={{marginTop: 50,height:50,width:50,backgroundColor:'red'}} >
                  <Text style={{height:50,width:50,backgroundColor:'red'}} >camera</Text>
              </TouchableOpacity>

              {this.state.visible ? this._renderMyView() : null}
            </View>

    );
}

}

Upvotes: 1

Related Questions