React - change this.state onClick rendered with array.map()
so based off your code you could do it a couple of ways.
onClick=(event) => this.gotoCoffee(event.target.value)
This looks like the approach you want.
onClick=() => this.gotoCoffee(c)
c
would be related to your item in the array.
You can pass index
of element to gotoCoffee
with closure in render
. Then in gotoCoffee
, just access that element as this.state.coffees[index]
.
gotoCoffee = (index) => {
this.setState({isLoading:true, select: this.state.coffees[index]})
setTimeout(()=>{
this.setState({isLoading:false,redirect:true})
},5000)
}
render(){
const data = this.state.coffees;
return (
<div>
<h1 className="title is-1"><font color="#C86428">Menu</font></h1>
<hr/><br/>
{data.map((c, index) =>
<span key={c}>
<div>
{this.state.isLoading && <Brewing />}
{this.renderCoffee()}
<div onClick={() => this.gotoCoffee(index)}
<strong><font color="#C86428">{c}</font></strong></div>
</div>
</span>)
}
</div>
);
}
}
All the answers look alright and working for you and it's obvious you made a mistake by not passing the correct value in click handler. But since you're new in this era I thought it's better to change your implementation this way:
It's not necessary use constructor at all and you can declare a state property with initial values:
class Menus extends Component{ state= { /* state properties */ }; }
When you declare functions in render method it always creates a new one each rendering which has some cost and is not optimized. It's better if you use currying:
handleClick = selected => () => { /* handle click */ } render () { // ... coffees.map( coffee => // ... <div onClick={ this.handleClick(coffee) }> // ... }
You can redirect with
history.replace
since you wrapped your component withwithRouter
and that's helpful here cause you redirecting on click and get rid ofrenderCoffee
method:handleClick = selected => () => this.setState( { isLoading: true}, () => setTimeout( () => { const { history } = this.props; this.setState({ isLoading: false }); history.replace(`/${coffee}`); } , 5000) );
Since Redirect
replaces route and I think you want normal page change not replacing I suggest using history.push
instead.