Rico Letterman
Rico Letterman

Reputation: 651

Different action for a click event

so I have a function bind to my button, that should perform different actions at each click; The return value will be used inside another getter, which I'll call inside render and thus making me unable to use setState on this case.

class awesomeFruits extends React.Component {

  ... constructor stuff etc

  clickSomething () {
    let fruit = 'banana'
    let clickThing = 1
    clickThing++

    // please notice that I only need 3 actions
    if (clickThing === 1) {
      fruit = 'apple'
    } else if (clickThing === 2) {
      fruit = 'grape'
    } else {
      fruit = 'pineapple'
      clickThing = 1 // reset click
    }

    return fruit
  }

  get fruitOfChoice () {
    ... non related stuff
    this.clickSomething()
  }
}

and then in my render function:

render () {
  return <button onClick={this.clickSomething.bind(this)}>CLICK FRUIT</button>
    <p>this.fruitOfChoice</p>
}

I'm learning React together with JS so I'm not sure if its mainly a React question. With vanilla JS I'm able to make it work by declaring clickThing to zero as a global variable, but I don't know how to do it properly with React.

To make question more precise: How can I have a different action on each click, updating the render with the result I want?

Any feedback appreciated, even if I have to remake all the above

Upvotes: 0

Views: 90

Answers (2)

jmealy
jmealy

Reputation: 592

The issue is in clickSomething's declaration. Every time it's executed, it resets clickThing to 1. As you indicate in your question, you'll need to move clickThing's initial declaration outside of the function's execution. Here's how I'd do it:

        class awesomeFruits {
            constructor() {
                this.fruits = ['banana', 'grape', 'pineapple'];
                this.clickThing = -1;  // Starting this out at -1 so the first execution increments it to 0, and it hits the first index of your fruits array;
            }
            clickSomething () {
                if(this.clickThing === (this.fruits.length - 1)) {
                   this.clickThing = 0;
                } else {
                   this.clickThing++;
                }
                return this.fruits[this.clickThing];
            }
        }

        const fruitPicker = new awesomeFruits;
        document.getElementById('testMe').addEventListener('click',() => {
            console.log(fruitPicker.clickSomething());
        })
<button id="testMe">Pick a fruit</button>

Putting the fruit names into the array is just cleaner, and allows you to add more later with minimal code.

Finally, it may not be what you're after, but if you'd ever like to output a random fruit, this.clickThing = Math.round(Math.random() * fruits.length-1) will give you a random number, not exceeding the highest index of the fruits array.

Upvotes: 1

Ahmed Eid
Ahmed Eid

Reputation: 4814

within any HTML tag always enclose your js code within {} . namely

<p> {this.fruitOfChoice } </p> 

within getFruitOfChoice you need to return a value because that is the function you are eventually calling .

return this.clickSomething()

Upvotes: 0

Related Questions