audaz802 audaz802 - 2 months ago 7
React JSX Question

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

Answer

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.

Comments