我当前正在映射一个数组以产生几个Font Awesome Icons。我有一个用作标记的OnClick方法:我只想更改单击项的图标。这是我的实现:
<FontAwesomeIcon id={i.key} onClick={this.ToggleIcon} icon={this.state.clicked ? faHeart : faCalendarAlt}/>
ToggleIcon = (e) =>{
if((this.state.clicked)){
this.setState({clicked: true})
}
else if!(this.state.clicked)){
this.setState({clicked: false})
}
}
但是,这将更改所有图标,而不仅仅是单击的图标。我该怎么做?
答案 0 :(得分:0)
您将要跟踪状态下单击对象的标识符,而不是简单的布尔值。
如果您一次只希望单击一个图标:
<FontAwesomeIcon id={i.key} onClick={e => this.ToggleIcon(e, i.key)} icon={this.state.clicked === i.key ? faHeart : faCalendarAlt}/>
ToggleIcon = (e, key) =>{
this.setState(prevState => {
...prevState,
clicked: prevState.clicked === key ? null : key
});
}
如果您要跟踪多个图标的点击状态:
import * as R from 'ramda';
...
// Init state with empty array
state = {
clicked: [],
// ...other state in this component
}
...
<FontAwesomeIcon id={i.key} onClick={e => this.ToggleIcon(e, i.key)} icon={R.includes(i.key, this.state.clicked) ? faHeart : faCalendarAlt}/>
ToggleIcon = (e, key) =>{
this.setState(prevState => {
if (!R.includes(key, prevState.clicked)) {
return {
...prevState,
clicked: R.append(key, prevState.clicked)
};
}
return {
...prevState,
clicked: R.without(key, prevState.clicked)
};
});
}
我在这里使用ramda
,但是您可以使用首选的操作数组的方法而不会发生突变。这也假设i.key
是每个图标的唯一标识符。
对于第二种情况,另一种方法是将每个图标包装在一个小组件中,该小组件处理自己的状态(看起来与您已经拥有的状态非常相似),出于性能方面的考虑,通常鼓励这样做。但是,是否最佳方法取决于这些图标的目的及其“已单击”状态的目的。
答案 1 :(得分:0)
您是否在同一组件上呈现所有这些图标?如果是这样,那就是您的问题。您正在更新整个组件的状态,因此状态值在整个地方都相等。那么解决方案是什么?正确,是为每个图标分配不同的clicked
状态键/值。
数组:
class Icons extends React.Component {
constructor(props) {
super(props)
this.state = {
icons: []
}
}
toggleIcon(index, event) {
const iconState = this.state.icons[index] || {}
this.setState({
...this.state,
icons: [
...this.state.icons.slice(0, index),
{
..._currentValue,
clicked: !iconState.clicked
},
...this.state.icons.slice(index + 1)
]
})
}
render() {
return (
<div>
{ ICONS.map((item, index) => {
const iconState = this.state.icons[index] || {}
return (
<FontAwesomeIcon id={index} onClick={this.toggleIcon.bind(this, index)} icon={iconState.clicked ? faHeart : faCalendarAlt} />
)
}) }
</div>
)
}
}
对象:
class Icons extends React.Component {
constructor(props) {
super(props)
this.state = {
icons: {
a: { clicked: false },
b: { clicked: false }
}
}
}
toggleIcon(key, event) {
this.setState({
...this.state,
icons: {
...this.state.icons,
[key]: {
...this.state.icons[key],
clicked: !this.state.icons[key].clicked
}
}
})
}
render() {
return (
<div>
<FontAwesomeIcon id={'a'} onClick={this.toggleIcon.bind(this, 'a')} icon={this.state.icons.a.clicked ? faHeart : faCalendarAlt} />
<FontAwesomeIcon id={'b'} onClick={this.toggleIcon.bind(this, 'b')} icon={this.state.icons.b.clicked ? 'icon 1' : 'icon 2' } />
</div>
)
}
}