React infinite loop – onClick inside a render calls setState()

Pretty new to React. I’m having some problems rendering a button component. What I’m trying to do is to create a button that, when clicked, fetches some data and displays it under the button itself as a list. To do so, I’m trying to do a conditional rendering.
I used the state of the button component as the number of data fetched, initialized to zero. So the first time I would only render the button and not try to render the list at all. When the button gets clicked, the onClick event executes the fetch, getting the data. At this point, the state should be updated, but if I call setState() to update it, of course React advises me with a warning that I’m creating a infinite loop (I’m calling setState() inside a render() function after all).

The most common lifecycle components are not helping me, since when the component gets mounted the user has not yet pressed the button (can’t use componentDidMount() then) , and if I remove the setState() from the onClick function the component does not update, so I’m out of methods to call setState() from. And given that a component changing its props by itself is anti-pattern, I’m out of ideas.

Here is the code:

import { MapList } from './MapList';

export class ButtonFetcher extends React.Component
{

    constructor(props)
    {
        super(props);

        this.state = { numberOfMaps: 0 };

        this.mapArray = [];

        this.fetchHaloMaps = this.fetchHaloMaps.bind(this);
    }

    async fetchHaloMaps()
    {
        const url = 'https://cryptum.halodotapi.com/games/hmcc/metadata/maps'   

        fetch(url, {
            "method": 'GET',
            "headers": {
                        'Content-Type': 'application/json',
                        'Cryptum-API-Version': '2.3-alpha',
                        'Authorization': 'Cryptum-Token XXX'
                     }
        })
        .then(response =>      
            response.json())   
        .then(res => {  
                    
            let d;
            let i=0;
            for (; i< res.data.length; i++)
            {
                d = res.data[i];
                this.mapArray[i] = d.name;
            }

            this.setState(({  
                numberOfMaps : i
            }));  
        })  
        .catch(error => {   
            console.log("There was an error: " + error);
        });
    }


    render()
    {
        if (this.state.numberOfMaps === 0)
        {
            return (
                <button type="button" onClick={this.fetchHaloMaps} >Retrieve giafra's last maps!</button>
            )
        }

        else
        {
            return (
                <div>
                    <button type="button" onClick={this.fetchHaloMaps} >Retrieve giafra's last maps!</button>
                    <MapList mapNames={this.mapArray} />
                </div> 
            )
        }
        
    }

}