Rodrigo M. F. Castilho
Rodrigo M. F. Castilho

Reputation: 152

Importing React component and using its method not working

This will likely have a pretty silly answer, but I have essentially found several Google pages of the same answer and it's not working for me.

Essentially, what I'm trying to do is, once an image is clicked, a modal is prompted to make sure the user really wants to navigate back to home page. Should they not want to, the modal component would no longer be rendered.

Modal.js looks like this:


export default class ExitModal extends Component {
    constructor(props){
        super(props);

        this.modalAppears = this.modalAppears.bind(this);
        this.modalDisappears = this.modalDisappears.bind(this);

        this.state = {
            visibility: false
        }
    }

    modalAppears() {
        this.setState = {
            visibility: true
        }
    }

    modalDisappears() {
        this.setState = {
            visibility: false
        }
    }


    render() {
        if(this.state.visibility == false){
            return null
        } else {
            return(
                <div className="exit-modal">
                    Content here
                </div>
            );
        }
    }
}

And the UI code looks like this:

import ExitModal from './components/ExitModal';
import logo from './assets/logo.png'

class UserInterface extends Component {
    constructor(props) {
        super(props);
        this.handleImgClick = this.handleImgClick.bind(this);
    }

    handleImgClick() {
        var modalOpener = new ExitModal();
        modalOpener.modalAppears();
    }

    render() {
        return(
            <img className="top-left-logo" src={ logo } onClick= { () => this.handleImgClick } />
        )
    }
}

I have used console logs to monitor whether or not the external function was being called, and it wasn't.

Any hints on what I'm doing wrong?

Upvotes: 0

Views: 690

Answers (2)

Deepak
Deepak

Reputation: 148

When state is updated the current component will be re-rendered with all its child component.

The UserInterface component goes below:

import React from 'react';
import ExitModal from './ExitModal';

class UserInterface extends React.Component {
    constructor(props) {
        super(props);
        this.openModal = this.openModal.bind(this);
        this.closeModal = this.closeModal.bind(this);
        this.state = {
            visibility: false
        }
    }

    openModal() {
        this.setState({visibility: true})
    }

    closeModal() {
        this.setState({visibility: false})
    }

    render() {
        return(
          <>
            <button onClick= { () => this.openModal() }>
              show
            </button>

            <button onClick= { () => this.closeModal() }>
              Remove
            </button>
            <ExitModal visibility={this.state.visibility}></ExitModal>
          </>
        )
    }
}

export default UserInterface;

The ExitModal component code goes below:

import React from 'react';

export default class ExitModal extends React.Component {
    render() {
        if(this.props.visibility === false){
            return null
        } else {
            return(
                <div className="exit-modal">
                    Content here
                </div>
            );
        }
    }
}

Upvotes: 0

Imran Rafiq Rather
Imran Rafiq Rather

Reputation: 8078

setState() is a method, not a property. use below

this.setState({

})

As I debugged the code there are other many problems that you need to look into.

  1. onClick= { () => this.handleImgClick } is not correct way of handling the click event. Either use onClick={() => this.handleImgClick()} (note the closed parenthesis () at the end) or simple use onClick={this.handleImgClick} which would be best in this case since we are not passing any value as parameter to the handleImgClick method.

  2. Second IMPORTANT thing is that, The ExitModal Component is not actually mounted into the DOM and you are creating its Object Directly and calling its method modalAppears(). This is ofCourse a bad practice and may result in bugs later.

    var modalOpener = new ExitModal();
    modalOpener.modalAppears();
    
  3. Now an easy way to do this is lift the state up to be controlled by UserInterface Component. And keep ExitModal as seperate Pure Component without any click handlers on it. Directly return the Code and control its opening and closing from the Parent Component (UserInterface) itself.

ExitModal Component will look like this(A pure React Component)

import React from 'react';

const ExitModal = () => {
 return (
  <div className="exit-modal">
   Content here !!! Set all the CSS required for a Modal to work
 </div>
 );
}
export default ExitModal;

UserInterface Component will handle state to manage Opening and Closing of Model.

import React, { Component } from 'react';
import ExitModal from './ExitModal';
import logo from './../logo.svg'

class UserInterface extends Component {
 constructor(props) {
  super(props);
  this.state = {
   visibility: false
  }
  this.handleImgClick = this.handleImgClick.bind(this);
 }

 handleImgClick() {
  this.setState({
   visibility: true
  })
 }

 render() {
  return (
   <main>
    <img className="top-left-logo" src={logo} onClick={this.handleImgClick} 
style={{ height: '10rem' }} />
    {
      this.state.visibility && <ExitModal />
    }
   </main>

   )
 }
}

export default UserInterface;

And to Hide the Modal on some other Event, you have set another Handler and set this.setState({visibility:false}) after carefully examining how to do it. You would need to pass a method as prop to ExitModal Component because the exit event will happen from ExitModal somewhere. Give this one a try :)

Upvotes: 3

Related Questions