简体   繁体   中英

ReactJS setState in map function

I have a map() function that loops over json data stored in the state of my class. In each loop, it displays a component that has an onClick mouse event set. It doesn't work and outputsan error "Error: Maximum update depth exceeded..." What can i do to make it work?

Here's a sample of the code i use:

The constructor of my class:

constructor(props) {
   super(props);
   this.state = {
     storeList:  storesLoc.stores,
     currentStoreName: storesLoc.stores[0].name,
     currentStoreCp:  storesLoc.stores[0].cp,
     currentStoreAddress:  storesLoc.stores[0].address
}

and the sample of code in the render method

<ul className="ul-locations">
{this.state.storeList.map((store, i) => (
 <li>
    <StoreItem  
     key={i} 
     cp={store.cp} 
     name={store.name} 
     selected={store.selected} 
     onClick={this.changeCityInfo(i)}/>
  </li>
  ))}
  <li>
     <Shuffle className="col-2"></Shuffle>
     <a href="#" className="ml-2 mr-2 col-10">Changer de Magasin</a></li>

you should pass a function reference to onclick, but you you executing it, and inside that you probably call some setState, hence infinite loop; wrap it with an arrow function that returns the function you want and you are good to go

onClick={()=>this.changeCityInfo(i)}/>

This invokes changeCityInfo function with argument i on each render.

onClick={this.changeCityInfo(i)} // Wrong expression, invokes the function

Instead, pass an arrow function with empty parameter list and call inside that function:

onClick={() => this.changeCityInfo(i)} // Correct expression, doesn't invoke but point

Now it will only get invoked on click.

Looks like a problem with the onClick prop that you are passing to StoreItem - try this instead:

<StoreItem 
    {...otherprops}
    onClick={() => this.changeCityInfo(i)}
/>

Explanation: You were getting the error because the function changeCityInfo was getting called for every iteration of the map function

Solution: In react whenever we have to handle events or pass function to another component we have to do it in the following way <button onClick={() => this.handleClick(arg)}> so in your case follow this:

 <StoreItem key={i} cp={store.cp} name={store.name} selected={store.selected} onClick={() => this.changeCityInfo(i)} />

Have a look at this and this doc from official react site you will get a better understanding of it

if you are using parameters, you can use something like this on onClick props

 <li>
    <StoreItem  
     key={i} 
     cp={store.cp} 
     name={store.name} 
     selected={store.selected} 
     onClick={() => this.changeCityInfo(i)}/> // try this
  </li>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM