如何在嵌套组件中呈现状态更改?

时间:2019-12-17 19:12:10

标签: javascript reactjs

我正在制作一个单页基于文本的游戏,除以有状态组件<UIPanel/>的多个实例。我之所以将其设为有状态,是因为它可以处理其在应用程序中的可见性和位置。我的“主”面板必须包含应用程序本身的信息,以便播放器单击“动作”按钮时,播放器资源会更新,这会反映在“资源”列中。

问题

点击ActionButton组件会按预期正确更新状态(已通过console.log和chrome的React Dev Console确认),但页面保持不变/未重新呈现。

我尝试过的事情

我发现,如果我从playerResourcePanel标签中取出<UIPanel/>,它们确实会更新。我不想将App的道具传递给<UIPanel/>道具的原因是因为并非所有UIPanel都需要此信息。我认为这个问题不是语法错误,而是来自对状态更新和组件嵌套如何工作的基本误解,但我不知道如何表达它来查找它。

摘要

如果更新变量位于另一个组件内部,如何在应用程序的render方法中正确反映状态变化?

按钮处理程序

energyButtonHandler = () => {
  this.setState(prevState => {
    const playerResources = {...prevState.playerResources}
      for (const key in prevState.playerResources) {
        playerResources[key] = prevState.playerResources[key]
      }
      playerResources.energy.amount += 1
      playerResources.currency.amount += Math.floor(Math.random() * 2); 
      return { playerResources }
})}

playerResourcePanel (在render()内部)

const playerResourcePanel = Object.getOwnPropertyNames(this.state.playerResources).map(name => {
  const resource = this.state.playerResources[name]
    let effectObject = ""
    let increasePerTick = resource.increasePerTick
    if (resource.isMinion){
      effectObject = this.state.minions[name].effect
      increasePerTick = undefined
    }
    return resource.hidden ? null : (
      <PlayerResource
        key = {resource.id} 
        iconImg = {resource.icon}
        name = {resource.displayName}
        amount = {resource.amount}
        increasePerTick = {increasePerTick}
        max = {resource.max}
        isMinion = {resource.isMinion}
        effectObject = {effectObject} />
)})

应用程序组件内部的UIPanel标签

<UIPanel header="Main Panel"
         key={this.state.panels.main.id}
         isTop >
  <Row>
    <Col md="2">
      <Row>
        <Col className="h5"> Actions </Col>
      </Row>
      <Row>
        <Col>
          <ActionButton
              iconImg = {this.state.fireIcon}
              click= {() => this.energyButtonHandler()}
              name='Pillage'/>
        </Col>
      </Row>
    </Col>
    <Col md="5">
      <Row>
        <Col className="h5"> Resources </Col>
      </Row>
      <Row>
        <Col>
          {playerResourcePanel}
        </Col>
      </Row>
    </Col>
  </Row>
</UIPanel>

0 个答案:

没有答案