Geoff_S
Geoff_S

Reputation: 5107

passing onCLick to imported component, react

I have code below of two components. One (medjournalcomponent.js) is a parent in this case. It is a page that houses an element called minicard, which is my imported minicardcomponent.js

The minicard shows up fine, but my problem is that I can't get an onclick to work for my modal code in terms of clicking on the minicard component.

I've tried to pass it to the component so that any click on the Column element in MiniCardComponent would open the modal, but it doesn't work. I'll get an error that it "Cannot read property onCLick of undefined"

What am I still doing wrong, and how can I make it so that a click on the imported MiniCardComponent will open the modal?

MiniCardComponent.js

function MiniCardComponent({ props, onClick, className = '', title, value }) {
const composedClassName = `${css(styles.container)} ${className}`;
return (
    <Column onClick={() => props.onClick}  flexGrow={1} className={composedClassName} horizontal="center" vertical="center">
        <span className={css(styles.title)}>{title}</span>
        <span className={css(styles.value)}>{value}</span>
    </Column>
);
}

export default MiniCardComponent;

MedJournalComponent.js

class MedJournalComponent extends React.Component {

      state = {
        open: false
      };

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

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

    render() {
        const { open } = this.state;
        return (
            <Column>

                <Row className={css(styles.cardsContainer)} wrap flexGrow={1} horizontal="space-between" breakpoints={{ 768: 'column' }}>
                    <Row className={css(styles.cardRow)} wrap flexGrow={1} horizontal="space-between" breakpoints={{ 384: 'column' }}>

                        <MiniCardComponent onClick={() => this.onOpenModal} className={css(styles.miniCardContainer)} title="Medical Journal" value= <FaBookMedical /> />

                        <Modal open={open} onClose={this.onCloseModal}>
                          <h2>Simple centered modal</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>
                    </Row>
                </Row>
            </Column>
        );
  }
}

Upvotes: 0

Views: 213

Answers (3)

Nick Kinlen
Nick Kinlen

Reputation: 1406

Made some edits to your code and got an onClick handler working in the child component. Check out this Code Sandbox.

Changed the onClick handler in the parent component to this:

<MiniCardComponent onClick={() => this.onOpenModal()}/>

And changed the child component to call it like this as an example:

<button onClick={props.onClick}>Click me</button>

Also got rid of the props destructuring in the child component. Looks like you just needed the function parenthesis in the parent component and not in the child component.

Also, you were missing a constructor in the parent component. Not sure if that effected this too.

Upvotes: 1

iamhuynq
iamhuynq

Reputation: 5529

You only need onClick, not props.onClick

<Column onClick={onClick}  flexGrow={1} className={composedClassName} horizontal="center" vertical="center">
        <span className={css(styles.title)}>{title}</span>
        <span className={css(styles.value)}>{value}</span>
</Column>

Upvotes: 0

Patrissol Kenfack
Patrissol Kenfack

Reputation: 863

The main problem is you have a bad signature of MiniCardComponent. Also think of difference between execute a function and set a function as parameter

So should do so:

function MiniCardComponent({ onClick, className = '', title, value, ...props }) {
const composedClassName = `${css(styles.container)} ${className}`;
return (
    <Column onClick={() => onClick()}  flexGrow={1} className={composedClassName} horizontal="center" vertical="center">
        <span className={css(styles.title)}>{title}</span>
        <span className={css(styles.value)}>{value}</span>
    </Column>
);
}

export default MiniCardComponent;

Upvotes: 0

Related Questions