0

I want to make nested component clickable and to know on which component is clicked.

I had tried to send variable but there are some issues.

If I write function with this.clickMe() it will be invoked at component load. if the function is written in this way this.clickMe without rounded brackets, the click event is invoked but I can not pass a parameter.

import React, { Component } from 'react';
import CategoryControlRow from './components/CategoryControlRow';
import './style.css';

/**
 * @class ./widgets/SeatMap/components/LeafletMap/components/CategoryControl
 */
class CategoryControl extends Component
{
    /**
     * TODO: This function supposed to be deleted.
     */
    clickMe = (text) =>
    {
        alert(text);
    };

    /**
     * @returns {XML}
     */
    render()
    {
        return (
            <div className="col-xs-12 col-md-3" id="categories">
                <p className="text-uppercase" id="filter">Ansicht Filtern</p>

                <CategoryControlRow class={'category purple'} clickMe={this.clickMe} categoryName={'1. Kategorie'} currency={'CHF'} value={"78.00"} />
                <CategoryControlRow class={'category orange'} clickMe={this.clickMe} categoryName={'2. Kategorie '} currency={'CHF'} value={"68.00"} />
                <CategoryControlRow class={'category green'} clickMe={this.clickMe} categoryName={'3. Kategorie'} currency={'CHF'} value={"58.00"} />
                <CategoryControlRow class={'category blue'} clickMe={this.clickMe} categoryName={'4. Kategorie'} currency={'CHF'} value={"48.00"} />

            </div>
        )
    }
}

export default CategoryControl;

Sub Component

import React, { Component } from 'react';
import './style.css';

/**
 * @class ./widgets/SeatMap/components/LeafletMap/components/CategoryControl/components/CategoryControlRow
 */
class CategoryControlRow extends Component
{
    /**
     * @returns {XML}
     */
    render() {
        return (
            <p className={"category " + this.props.class} onClick={this.props.clickMe}>
                {this.props.categoryName}
                <span>
                    {this.props.currency} {this.props.value}
                </span>
            </p>
        )
    }
}

export default CategoryControlRow;

5 Answers 5

2

Write it like this

<CategoryControlRow class={'category purple'} clickMe={(event) => this.clickMe(event, "value1", "value2")} categoryName={'1. Kategorie'} currency={'CHF'} value={"78.00"} />

Instead of value1 and value2, you can pass any number of arguments

Sign up to request clarification or add additional context in comments.

Comments

1

For CategoryControl component, add constructor below as following;

import React, { Component } from 'react';
import CategoryControlRow from './components/CategoryControlRow';
import './style.css';

class CategoryControl extends Component
{
    // Add this constructor
    constructor(props) {
        super(props);
        this.clickMe = this.clickMe.bind(this);
    }

    clickMe = (text) =>
    {
        alert(text);
    };

    render()
    {
        return (
            <div className="col-xs-12 col-md-3" id="categories">
                <p className="text-uppercase" id="filter">Ansicht Filtern</p>

                <CategoryControlRow class={'category purple'} clickMe={this.clickMe} categoryName={'1. Kategorie'} currency={'CHF'} value={"78.00"} />
                <CategoryControlRow class={'category orange'} clickMe={this.clickMe} categoryName={'2. Kategorie '} currency={'CHF'} value={"68.00"} />
                <CategoryControlRow class={'category green'} clickMe={this.clickMe} categoryName={'3. Kategorie'} currency={'CHF'} value={"58.00"} />
                <CategoryControlRow class={'category blue'} clickMe={this.clickMe} categoryName={'4. Kategorie'} currency={'CHF'} value={"48.00"} />

            </div>
        )
    }
}

export default CategoryControl;

And for the CategoryControlRow sub component, add constructor, event handler function and edit your onClick attribute in p element as following;

import React, { Component } from 'react';
import './style.css';

class CategoryControlRow extends Component
{
    // Add this constructor
    constructor(props) {
        super(props);
    }

    // Add this event handler function
    onClickParagraph = categoryName => {
        this.props.clickMe(categoryName);
    };

    render() {
        return (
            <p className={"category " + this.props.class} 
               /* Edit onClick like this*/ 
               onClick={this.onClickParagraph.bind(this, this.props.class)}>
                  {this.props.categoryName.YOUR_FIELD_NAME}
                  <span>
                      {this.props.currency.YOUR_FIELD_NAME} 
                      {this.props.value.YOUR_FIELD_NAME}
                  </span>
            </p>
        )
    }
}

export default CategoryControlRow;

Comments

1

In your CategoryControlRow, you can do the following:

  • Create a constructor, where you do this.onClick = this.onClick.bind(this), to make it keep a reference to the correct "this"
  • Create a function onClick() { this.props.onClick(this.props.categoryName); } or whatever data you want to use to identify your component
  • Set onClick={this.onClick} on your p

Edit: you can use arrow function for onClick to avoid the bind(this) trick, but this has a little performance cost in many cases so I prefer the bind version.

Comments

1
<CategoryControlRow class={'classname'} clickMe={(event) => this.clickMe(event, parameterlist)} categoryName={categoryobject} currency={currencyobj} value={valueobject} />

Every thing in child component you get as a props:

import React, { Component } from 'react';
import './style.css';

/**
 * @class ./widgets/SeatMap/components/LeafletMap/components/CategoryControl/components/CategoryControlRow
 */
class CategoryControlRow extends Component
{
    /**
     * @returns {XML}
     */
    render() {
        return (
            <p className={"category " + this.props.class} onClick={this.props.clickMe}>
                {this.props.categoryName.YOUR_FIELD_NAME}
                <span>
                    {this.props.currency.YOUR_FIELD_NAME} {this.props.value.YOUR_FIELD_NAME}
                </span>
            </p>
        )
    }
}

export default CategoryControlRow;

Comments

1

the method:

clickMe = (e) =>{
    alert(e.target.whateverYouNeed);
}

The element:

<CategoryControlRow class={'category purple'} clickMe={(e)=>this.clickMe(e)} categoryName={'1. Kategorie'} currency={'CHF'} value={"78.00"} />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.