Shubham
Shubham

Reputation: 187

Not able to call a method outside render from a function inside render

class TableView extends React.Component {  
    state = {
        open: false,
    };

    onOpenModal = () => {
        this.setState({ open: true });
    };

    onCloseModal = () => {
        this.setState({ open: false });
    };

    render() {
        function showHistory() {
            this.onOpenModal; // not able to do this
            console.log(this.state.open); // or this
        }
        return (
             //...
             //...
            <Modal open={this.state.open} onClose={this.onCloseModal} center>
                <h2>History</h2>
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                    pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet
                    hendrerit risus, sed porttitor quam.
                </p>
            </Modal>
       );
   }
}

I am able to hit showHistory method on click of a button inside a jsx. But,when I try to call onOpenModal from showHistory, it throws error -

Uncaught TypeError: Cannot read property 'onOpenModal' of undefined

How do I call onOpenModal from showhistory ?

Upvotes: 1

Views: 1316

Answers (4)

andriusain
andriusain

Reputation: 1207

Firstly you are not calling onOpenModal, you are missing the parenthesis: this.onOpenModal() secondly you have to bind showHistory to this. Hope it helps:

class TableView extends React.Component {  
    state = {
        open: false,
    };

    onOpenModal = () => {
        this.setState({ open: true });
    };

    onCloseModal = () => {
        this.setState({ open: false });
    };

    render() {
        function showHistory() {
            this.onOpenModal(); // not able to do this
            console.log(this.state.open); // or this
        }.bind(this);
        return (
             //...
             //...
       );
   }
}

Upvotes: 1

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15292

I am not sure why you want to define function inside render if its possible to define at class/component level.

Within class/component,you can place it parallel to render.

showHistory = ()=> {
    this.onOpenModal(); // not able to do this
    console.log(this.state.open); // or this
}

Or if you want to go with same code placing,defined inside render using arrow function

const showHistory = () =>{
            this.onOpenModal; // not able to do this
            console.log(this.state.open); // or this
        }

And from html invoke it like this showHistory()

Upvotes: 0

Harikrishnan
Harikrishnan

Reputation: 1097

You need to bind the method in the constructor or you can bind it when it is called,

 class TableView extends React.Component { 
       constructor(props){
       this.state = {
            open: false,
        };
       this.onOpenModal = this.onOpenModal.bind(this)
       this.onCloseModal = this.onCloseModal.bind(this)
         } 
        onOpenModal = () => {
            this.setState({ open: true });
        };

        onCloseModal = () => {
            this.setState({ open: false });
        };

        render() {
            function showHistory() {
                this.onOpenModal; // not able to do this
                console.log(this.state.open); // or this
            }
            return (
                 //...
                 //...
                <Modal open={this.state.open} onClose={this.onCloseModal} center>
                    <h2>History</h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                        pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet
                        hendrerit risus, sed porttitor quam.
                    </p>
                </Modal>
           );
       }
    }

Also please note ,
In your case ,state declared as a class properties and not an instance property.

 state = {} //class property will not available on this object

Either do state declaraion in constructor

constructor() {
  this.state = {};   // now state available on this object
}

or remove this when referring state.It is better to declare state in constructor as you are using the method this.setState

Upvotes: 0

Pixelomo
Pixelomo

Reputation: 6737

try this, you might just need the parenthesis

this.onOpenModal()

failing that move the function outside of the render

class TableView extends React.Component {  
    state = {
        open: false,
    };

    onOpenModal = () => {
        this.setState({ open: true });
    };

    onCloseModal = () => {
        this.setState({ open: false });
    };

    showHistory() {
        () => this.onOpenModal() // not able to do this
        console.log(this.state.open); // or this
    }

    render() {
        return (
             //...
             //...
            <Modal open={this.state.open} onClose={this.onCloseModal} center>
                <h2>History</h2>
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                    pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet
                    hendrerit risus, sed porttitor quam.
                </p>
            </Modal>
       );
     }
   }

it could be that you need to bind this, the simplest way to do this is using fat arrow functions

() => this.onOpenModal()

Upvotes: 0

Related Questions