我正在写一个Box组件
我写了这个组件,它工作正常。
现在我想改进我的组件。我需要在我的父页面上显示多个Box,当我点击一个Box时,我想重置其余Box组件显示在父级上的状态,所以当我在盒子之间移动鼠标时,他们的样式需要更改,当我点击时其中一个然后选择Box的边框需要改变。
这是Box组件:
const STYLE = {
boxMouseOver: {...},
boxMouseOut: {...},
boxOn: {...},
}
export default class ClickableBox extends React.Component {
constructor (props) {
super(props)
this.state = {
mouseOver: false,
turnOn: false
}
}
handleMouseOver = () => {
this.setState({
mouseOver: true
})
}
handleMouseOut = () => {
this.setState({
mouseOver: false
})
}
handleOnClick = () => {
this.setState({
turnOn: !this.state.turnOn
});
this.props.resetStateCallback();
}
resetState = () = => {
this.setState({
turnOn: false
});
}
render () {
let style = this.state.mouseOver ? STYLE.boxMouseOver : STYLE.boxMouseOut
style = this.state.turnOn ? STYLE.boxOn : style
return (
<div style={style} onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onClick={this.handleOnClick}>
<span style={STYLE.title}>{this.props.title}</span>
<br/>{this.state.turnOn ? "on" : "off"}
</div>
)
}
}
这是父组件:
export default class GroupOfBoxes extends React.Component {
reset () {
alert('reset')
// **** I need help for this part ****
// Need to be called resetState() method on
// ClickableBox components shows on this page
for (currentBox : ?????) {
if (currentBox != selected Box??) {
currentBox.resetState()
}
}
}
render () {
return (
<div>
<Grid>
<Row className='show-grid'>
<Col sm={12}>
<ClickableBox title='1' resetStateCallback={this.reset} />
<ClickableBox title='2' resetStateCallback={this.reset} />
<ClickableBox title='3' resetStateCallback={this.reset} />
<ClickableBox title='4' resetStateCallback={this.reset} />
</Col>
</Row>
<Row className='show-grid'>
<Col sm={12}>
<ClickableBox title='5' resetStateCallback={this.reset} />
<ClickableBox title='6' resetStateCallback={this.reset} />
<ClickableBox title='7' resetStateCallback={this.reset} />
<ClickableBox title='8' resetStateCallback={this.reset} />
</Col>
</Row>
</Grid>
</div>
)
}
}
我不知道从父页面更改Box组件状态,因为我需要在父页面上引用我的Box组件,并在ClickableBox.resetState()
方法的每个ClickableBox
组件上调用GroupOfBoxes.reset()
方法。
----更新----
在我阅读了更多与React相关的文档后,我能够使我的代码工作,但我认为我的解决方案远非最佳。我将不胜感激任何优化的帮助。
所以我使用ref
属性来获取对我的Box组件的引用,并且我写了很多条件来决定需要重置哪些Box组件:
首先,我对ClickableBox组件进行了更改,我在resetStateCallback方法调用中添加了一个'this'参数:
handleOnClick = () => {
this.setState({
turnOn: !this.state.turnOn
});
this.props.resetStateCallback(this);
}
然后我将ref键添加到父组件:
<ClickableBox ref='box1' title='1' body='...' footer='...' resetStateCallback={this.reset} />
<ClickableBox ref='box2' title='2' body='...' footer='...' resetStateCallback={this.reset} />
...
最后我在父组件上修改了reset()方法:
(这种方法看起来很难看,所以如果可以,请帮我优化一下)
reset(comp) {
if (comp.props.title === '1') {
this.refs.box2.resetState()
this.refs.box3.resetState()
this.refs.box4.resetState()
this.refs.box5.resetState()
this.refs.box6.resetState()
this.refs.box7.resetState()
this.refs.box8.resetState()
} else if (comp.props.title === '2') {
this.refs.box1.resetState()
this.refs.box3.resetState()
this.refs.box4.resetState()
this.refs.box5.resetState()
this.refs.box6.resetState()
this.refs.box7.resetState()
this.refs.box8.resetState()
} else if (comp.props.title === '3') {
this.refs.box1.resetState()
this.refs.box2.resetState()
this.refs.box4.resetState()
this.refs.box5.resetState()
this.refs.box6.resetState()
this.refs.box7.resetState()
this.refs.box8.resetState()
} else if (comp.props.title === '4') {
...
} else if (comp.props.title === '5') {
...
} else if (comp.props.title === '6') {
...
} else if (comp.props.title === '7') {
...
} else if (comp.props.title === '8') {
...
}
}
我会把所有的盒子包在BoxWrapper
里面。 BoxWrapper在其州有两个属性:mouseOverIndex
和clickedIndex
。
它将这个状态传递给它的孩子。这样,所有逻辑都保存在包装器中,而Box
不需要知道其兄弟姐妹的状态。