jrz
jrz

Reputation: 1387

Function in react does not work as expected

I am trying to write a function that handles a button click. I want things to happen:

  1. The function gets a string and changes the state named "chosenGenre" to the given string.

  2. When a certain button is clicked, it calls the function and returns a string.

  3. The string/state "chosenGenre" is saved so I can use it later in another component.

This is what I have wrote but I think the way I deliver the string after the button is clicked isn't right.

import React, { Component } from 'react';
import Genre from './Genre';
import './GenreSelectPage.css';
import Blues from '../Blues.png';
import Classical from '../Classical.png'; 
import Country from '../Country.png';


export default class GenreSelectPage extends Component{

    state = {
        chosenGenre: ""
    }

    handleClick = (genreName) => {
        this.setState({chosenGenre: genreName});
    } 


    render(){
        return(
        <div className = "GenreSelectPage">
        <h3>Select your desired Kollab Room Genre</h3>
        <Genre genrePicture= {Blues} genreClicked = {this.handleClick("blues")}/>
        <Genre genrePicture= {Classical} genreClicked = {this.handleClick("Classical")}/>
        <Genre genrePicture= {Country} genreClicked = {this.handleClick("Country")}/>
        )
      }
    }

What should I change in order to call the function in the right way and keep the result?

Upvotes: 1

Views: 77

Answers (1)

Aprillion
Aprillion

Reputation: 22304

the problem is this.handleClick("blues") is executed during render, it returns undefined, similar to genreClicked={undefined}, with a side effect to schedule 3 asynchronous setStates...

you can use a factory function that returns an event handler function with access to a closure variable:

makeHandleClick = (genreName) => (event) => {
  this.setState({ chosenGenre: genreName });
  // console.assert(this.state.chosenGenre); // FYI: not possible, setState is async
}

render() {
  ...<Genre genrePicture={Blues} genreClicked={this.makeHandleClick("blues")} />

Upvotes: 1

Related Questions