我正在制作一个单页基于文本的游戏,除以有状态组件<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>