如何在单击时从另一个兄弟组件中增加一个值?
Posted
技术标签:
【中文标题】如何在单击时从另一个兄弟组件中增加一个值?【英文标题】:How to increment a value in one sibling component from another on click? 【发布时间】:2019-02-13 11:07:03 【问题描述】:function LeagueBadge(props)
return (
<img src=props.badgeUrl />
);
class LeagueInfo extends Component
constructor(props)
super(props);
this.state =
amountOfPlayers: null,
rpPerSecond: null,
rpCost: null,
;
render()
return (
<div>
<h4>this.props.name players: this.props.amountOfPlayers</h4>
<h4>RP per second: this.props.rpPerSecond</h4>
<h4>RP cost: this.props.rpCost</h4>
</div>
);
class League extends Component
render()
return (
<div>
<LeagueBadge badgeUrl=this.props.badge />
<LeagueInfo name=this.props.name />
</div>
);
class App extends Component
render()
return (
<div className="App">
<h1>Players</h1>
<League name="Bronze" badge= require('./bronze.png') ></League>
<League name="Silver" badge= require('./silver.png') ></League>
<League name="Gold" badge= require('./gold.png') ></League>
<League name="Platinum" badge= require('./platinum.png') ></League>
<League name="Diamond" badge= require('./diamond.png') ></League>
<League name="Master" badge= require('./master.png') ></League>
<League name="Challenger" badge= require('./challenger.png') ></League>
</div>
);
我希望能够单击作为 LeagueBadge 组件的图像,并在其兄弟 LeagueInfo 中增加 amountOfPlayers 的值。我已经用谷歌搜索了反应兄弟姐妹的交流,只找到了带有输入标签和 onChange 的示例,但在这里我想要 img 标签或按钮和 onClick。
【问题讨论】:
【参考方案1】:您可以将amountOfPlayers
的状态提升到您的<Leauge />
组件中,这样:
- 可以从<LeagueBadge />
触发更新
- 而且,该状态可以传递给您的 <LeagueInfo />
组件
这将允许您根据需要在 <LeagueInfo />
和 <LeagueBadge />
兄弟姐妹之间共享和同步状态。
为此,您需要向<LeagueBadge />
添加一个onClick
回调,当点击img
元素时会触发该回调。在<Leauge />
渲染方法中,您可以提供在<Leauge />
中增加amountOfPlayers
状态的逻辑。当amountOfPlayers
增加并调用setState
时(在<Leauge />
中),这反过来会导致您的<Leauge />
组件重新渲染自己(和孩子/兄弟姐妹)。因为amountOfPlayers
的更新值作为prop 传递给<LeagueInfo />
组件,所以这个更新值将在<LeagueInfo />
中呈现——有效地实现您所追求的。
这样的事情可能对你有用:
class LeagueBadge extends Component
render()
// Add props.onClick callback to trigger click event in <League />
// component
return (
<img src=this.props.badgeUrl
onClick=() => this.props.onClick() />
);
class LeagueInfo extends Component
constructor(props)
super(props);
this.state =
// amountOfPlayers: null, // This is not needed, as it's supplied by props
rpPerSecond: null,
rpCost: null,
;
render()
return (
<div>
<h4>this.props.name players: this.props.amountOfPlayers</h4>
<h4>RP per second: this.props.rpPerSecond</h4>
<h4>RP cost: this.props.rpCost</h4>
</div>
);
class League extends Component
componentWillMount()
this.setState(
amountOfPlayers : 0
)
render()
// Locally defined function that increments amountOfPlayers and
// updates state
const incrementAmountOfPlayers = () =>
this.setState( amountOfPlayers :
this.state.amountOfPlayers + 1 )
return (
<div>
<LeagueBadge badgeUrl=this.props.badge
onClick= () => incrementAmountOfPlayers() />
<LeagueInfo name=this.props.name amountOfPlayers= this.state.amountOfPlayers />
</div>
);
【讨论】:
目前我只复制粘贴了您的解决方案,但它在<img src=props.badgeUrl alt="missing alt text" onClick=() => this.props.onClick() />
PS 中显示错误“TypeError:无法读取未定义的属性'props'”。我通过从第二个道具中删除 this.
来修复它
@Megoh 刚刚更新 - 你现在应该可以复制了
不确定我是否需要在那里上课。也许未来只是功能就足够了
@Megoh 你的意思是<LeagueBadge />
组件?如果您希望我更新该答案以使其成为功能组件,请告诉我
我已经让 LeagueBadge 成为一个功能组件,并从第二个道具中删除了 this.
以使其工作。非常感谢,我很高兴在这么多天后解决了这个问题。【参考方案2】:
将您的状态保存在联赛组件中,并将负责更改它的函数传递给 LeagueBadge,例如:
class League extends Component
constructor(props)
super(props);
this.state =
amountOfPlayers: null,
;
handleClick = () =>
this.setState(prevState =>
return amountOfPlayers: prevState.amountOfPlayers + 1
)
render()
return (
<div>
<LeagueBadge badgeUrl=this.props.badge incrementPlayers=this.handleClick/>
<LeagueInfo name=this.props.name amountOfPlayers=this.state.amountOfPlayers/>
</div>
);
function LeagueBadge(props)
return (
<img src=props.badgeUrl onClick=this.props.incrementPlayers/>
);
在您的信息组件中使用this.props.amountOfPlayers
。
【讨论】:
我也会检查您的解决方案,如果可行,请点赞。它可以工作,但是它在开头显示 null 而不是 0,但这没什么大不了的。以上是关于如何在单击时从另一个兄弟组件中增加一个值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在将 Tablayout 与 viewpager 一起使用时从另一个片段调用 AsyncTask?