Q:

React - Updating a components state after fetch

I'm building a dashboard which sends fetch requests to a number of endpoints to check they're working. If they're working/broken I want to update the state of that component to reflect this i.e. show a tick/cross. I've already got this working with jQuery but I'm migrating it to React, here's a screenshot of the jQuery version:

Each api requires a secret, so for example take this data, bot3 doesn't have a secret, I also want to update component state in this case:
let b = [
  {
    name: 'bot1',
    secret: 'fgadfgfdg33fdfs',
  },
  {
    name: 'bot2',
    secret: 'fgadfgfdg33fdfs',
  },
  {
    name: 'bot3',
    secret: ''
  }
]

My list of bots is rendered using .map
{this.state.bots.map(bot => 
      <tr key={bot.name} id={bot.name} >
        <td>{bot.name}</td>
        <Bot stg="dev status" />
        <Bot stg="stg status" />
        <Bot stg="pro status" />
      </tr>
    )}

When making the request I .map through all bots again and pass their secret to a fetch request. 
this.state.bots.map(bot => {
  return this.healthcheck(address, env, bot[env], bot.name)
})

In my jQuery version I would first check the secret exists before making the call:
if(bot.secret === ''){
        $('#'+ bot.name +' .' + env + ' i').text('help_outline').removeClass('loading')
    } else {
        $('#'+ bot.name +' .' + env + ' i').text('autorenew').addClass('loading')
        healthcheck(address, env, bots[index][env], bot.name)
    }

The healthcheck function sends a fetch request:
healthcheck(address,env,secret,name){

fetch( address + 'v3/api/conversations', {
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        "authorization": "Bearer " + secret,
        'Content-Type': 'application/json',
    }
})
.then((response) => {
  return response.text();
})
.then((data) => {
  let d = JSON.parse(data)
  if(d !== undefined){
    // working bot
    // update state of this component to working
  } else{
    // broken bot
    console.log( name + ' ' + env + ' is broken')
    // update state of this component to broken
  }
})
.catch((error) => {
  console.log(error)
})

}
Now with jQuery it's very simple to update a single node for example a broken bot I can update with:
$('#'+ name +' .'+ env +' i').text('cancel').removeClass('loading')

This changes the text to cancel which changes the icon and removes the loading class so the icon stops rotating
I have looked at using React refs to target each node but apparently this is bad practice. What's frustrating is that every single example I can find of updating component state shows me how to do it using onClick, how do I attach an eventListener or update this state without a click?
Here's my code, sadly couldn't get it running on here or jsfiddle, it works using the create-react-app repo though
https://codesandbox.io/s/m4wl35671x

A:

If I am understanding you correctly, your App component is the one doing all the fetching, and you want the Bots to change their className based on the responses?
If so, there are a lot of ways to achieve this.
You could store the response after the AJAX call in the <App /> state, and then pass it down as props to <BotList /> which then should pass it again to each of the <Bot />. The <Bot /> should then decide which className to apply based on the received props.
Seems like a hassle passing the props all the way down? Yeah, it is, and this is just passing the props 2 level deep. It is stuffs like this that made people use Redux with React.
OR
You could just move the AJAX call to the <Bot /> component. Let each Bot make their own AJAX call, get the response and update their state accordingly. And finally, use that to decide which className to be applied.
UPDATE:
When you create an instance of component like this <Bot stg="something" />
The Bot component can access it from this.props.stg or props.stg in constructor. 
Using this technique, you can make 3 different Bots with different props like
<Bot name="bot1" />
<Bot name="bot2" />
<Bot name="bot3" />

Then, in the Bot componentDidMount(), you could make an AJAX call based on this.props.name, so each Bot can make a different AJAX call. 
You could then update the state of the Bot based on the response using this.setState.
Finally, in the render function, you could make a switch case to decide which className to use. Simple example:
let className = '';
switch(this.state.status){
   case 'working': classname = 'working icon-check'; break;
   case 'down': classname = 'down icon-disabled'; break;
}
return <div className={className}>something</div>;

I hope this helps.

