嗨,我是ReactJS的初学者,我正在用它制作记忆游戏,并且在揭示瓷砖时遇到问题。我希望在父组件的状态中有一些值,比如firstPick,secondPick,pickCount以及isHidden(这会切换图标可见性)。但是将它放在父组件中可以点击每个图块上的任何按钮切换图标。为了解决这个问题,我将isHidden属性移动到Button(子)组件。现在我想从其父组件中操纵Button的状态,因此我找到了有关在互联网中某处使用refs的信息。但是使用它们会使点击每个按钮只切换容器中的最后一个按钮。我想我搞砸了什么。所以我的Button组件看起来像这样:
class Button extends Component {
state = {isHidden: true};
toggleHidden () {
this.setState({isHidden: !this.state.isHidden});
}
render() {
return (
<div>
<button className="tile" onClick={this.props.onClick}>
<i
className={this.props.icon}
style={
this.state.isHidden ? { display: "none" } : { display: "block" }
}
/>
</button>
</div>
);
}
}
我的Board组件如下所示:
class Board extends Component {
state = { firstPick: "", secondPick: "", pickCount: 0 };
constructor(props) {
super(props);
this.buttonElement = React.createRef();
}
handleClick = () => {
this.buttonElement.current.toggleHidden();
this.setState({
firstPick: this.icon,
pickCount: this.state.pickCount + 1
});
alert(this.state.firstPick);
};
render() {
return (
<div className="board">
<div className="container">
<div className="row align-items-start">
<div className="col-3">
<Button
ref={this.buttonElement}
icon={animalArray[0]}
onClick={this.handleClick}
/>
当然,这里还有11个其他Button组件,但它们看起来完全一样。 (顺便问一下有没有办法不重复这段代码?它们放在bootstrap容器中)。我也有1个奖金问题。有没有办法将state.firstPick设置为icon属性?我不知道如何从Parent组件方法引用此值。我试着写这个.icon,但我认为它不起作用。我想在状态变量中保留两个选项,然后比较它们。或者有没有更好的方法来解决这个问题?谢谢
为什么不直接处理按钮本身的切换?
class Button extends Component {
state = {isHidden: true};
toggleHidden () {
this.setState({isHidden: !this.state.isHidden});
}
onClick = () => {
this.toggleHidden();
if (this.props.onClick) {
this.props.onClick();
}
}
render() {
return (
<div>
<button className="tile" onClick={this.onClick}>
<i
className={this.props.icon}
style={
this.state.isHidden ? { display: "none" } : { display: "block" }
}
/>
</button>
</div>
);
}
}
更新:要保留firstPick
的唯一引用,您可以将handleClick
包装在另一个函数中:
handleClick = (icon) => () => {
this.buttonElement.current.toggleHidden();
this.setState({
firstPick: icon,
pickCount: this.state.pickCount + 1
});
alert(this.state.firstPick);
};
render() {
return (
<div className="board">
<div className="container">
<div className="row align-items-start">
<div className="col-3">
<Button
ref={this.buttonElement}
icon={animalArray[0]}
onClick={this.handleClick(animalArray[0])}
/>
handleClick
现在变成一个返回原始函数的函数(带有一些额外的/唯一的上下文,在本例中为animalArray[0]
)。
我会说你的项目的复杂性足以保证像flux或redux这样的商店跟踪你所有的按钮属性。这通常是父元素和子元素之间复杂关系的解决方案。
在我看来,refs应该只用于不受控制的组件,即页面上没有反应的任何元素。