React - 获取后更新组件状态

时间:2017-12-20 02:31:21

标签: jquery reactjs fetch state

我正在构建一个仪表板,它将获取请求发送到多个端点以检查它们是否正常工作。如果它们正在工作/损坏,我想更新该组件的状态以反映这一点,即显示勾选/交叉。我已经使用jQuery了,但我正在将它迁移到React,这是jQuery版本的截图:

enter image description here

每个api都需要一个秘密,所以例如拿这个数据,bot3没有秘密,我也想在这种情况下更新组件状态:

let b = [
  {
    name: 'bot1',
    secret: 'fgadfgfdg33fdfs',
  },
  {
    name: 'bot2',
    secret: 'fgadfgfdg33fdfs',
  },
  {
    name: 'bot3',
    secret: ''
  }
]

我的机器人列表是使用.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>
    )}

再次通过所有机器人发出请求.map并将其秘密传递给获取请求。

this.state.bots.map(bot => {
  return this.healthcheck(address, env, bot[env], bot.name)
})

在我的jQuery版本中,我首先会在拨打电话之前检查秘密是否存在:

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)
    }

healthcheck函数发送获取请求:

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)
})

}

现在使用jQuery更新单个节点非常简单,例如我可以更新的破坏的僵尸程序:

$('#'+ name +' .'+ env +' i').text('cancel').removeClass('loading')

这会将文本更改为取消,这会更改图标并删除加载类,以便图标停止旋转

我已经看过使用React refs来定位每个节点,但显然这是不好的做法。令人沮丧的是,我可以找到更新组件状态的每个示例向我展示了如何使用onClick执行此操作,如何附加eventListener或更新此状态而不单击?

这是我的代码,遗憾的是无法让它在这里运行或jsfiddle,它使用create-react-app repo虽然

https://codesandbox.io/s/m4wl35671x

1 个答案:

答案 0 :(得分:1)

如果我理解正确,那么您的App组件就是进行所有提取的组件,并且您希望Bots根据响应更改其className?

如果是这样,有很多方法可以实现这一目标。

您可以在<App />状态的AJAX调用之后存储响应,然后将其作为道具传递给<BotList />,然后再将其传递给每个<Bot />。然后,<Bot />应根据收到的道具决定应用哪个className。

似乎麻烦一直把道具传递下来?是的,它是,这只是通过2级深的道具。这样的东西让人们使用Redux和React。

OR

您可以将AJAX调用移至<Bot />组件。让每个Bot进行自己的AJAX调用,获取响应并相应地更新其状态。最后,使用它来决定要应用哪个className。

更新: 当您创建像<Bot stg="something" />这样的组件实例时 Bot组件可以在构造函数中从this.props.stgprops.stg访问它。 使用这种技术,你可以使用不同的道具制作3个不同的机器人,如

<Bot name="bot1" />
<Bot name="bot2" />
<Bot name="bot3" />

然后,在Bot componentDidMount()中,您可以基于this.props.name进行AJAX调用,因此每个Bot可以进行不同的AJAX调用。

然后,您可以使用this.setState根据回复更新Bot的状态。

最后,在render函数中,您可以创建一个switch case来决定使用哪个className。简单的例子:

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>;

我希望这会有所帮助。