有条件地渲染“真棒字体”图标

时间:2019-04-14 23:32:29

标签: reactjs

我当前正在映射一个数组以产生几个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})
  }
}

但是,这将更改所有图标,而不仅仅是单击的图标。我该怎么做?

2 个答案:

答案 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>
    )
  }
}

了解更多信息: https://reactjs.org/docs/state-and-lifecycle.html