Toggling Font Awesome 5 icon with React

user8679481 picture user8679481 · Dec 8, 2017 · Viewed 12.2k times · Source

I am trying to toggle a Font Awesome icon by clicking on a to-do list item. Here is the entire component...

import React from 'react';

import './TodoItem.scss';

class TodoItem extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      complete: false
    }
    this.toggleComplete = this.toggleComplete.bind(this);
  }

  toggleComplete() {
    this.setState(prevState => ({
      complete: !prevState.complete
    }));
  }

  render() {
    const incompleteIcon = <span className="far fa-circle todo-item-icon"></span>;
    const completeIcon = <span className="far fa-check-circle todo-item-icon"></span>;

    return (
      <div className="todo-item" onClick={this.toggleComplete}>
        {this.state.complete ? completeIcon : incompleteIcon}
        <span className="todo-item-text">{this.props.item}</span>
      </div>
    );
  }
}

export default TodoItem;

Here's my FA 5 CDN (straight from the website)...

<script defer src="https://use.fontawesome.com/releases/v5.0.1/js/all.js"></script>

I've taken a few screenshots of the React dev tool and inspector...

Here is the React component while incomplete (the default) React component while incomplete

And while complete... React component while complete

And the two icon elements in the inspector, I noticed the one not being used by default is commented out. enter image description here

As you can see, I'm able to manually toggle the complete state and the component changes in the React tool but the change is not rendered. I changed the default state to make sure both icons are loaded correctly and they are. I made a Codepen to try it in a different environment and this one works, but I am using the FA 4.7.0 CDN. With the Codepen and FA 4.7.0, when I inspect the icon, it is just an HTML element not SVG.

I'd like to get this component working with FA 5 so any help would be appreciated!

Answer

brkn picture brkn · Dec 24, 2017

The font-awesome javascript doesn't rerender on a React rerender trigger. If you are okay with not using the new font-awesome svg/javascript icons, you can use font-awesome as a webfont with css.

In your index.html, delete the fontawesome script, and add the font-awesome css stylesheet:

<link href="https://use.fontawesome.com/releases/v5.0.2/css/all.css" rel="stylesheet">

Your code should work now.


The other possibility is to use the official font-awesome react package (it's a bit more of a hassle, but it uses the new svg icons)

Add necessary packages to project:

yarn add @fortawesome/fontawesome @fortawesome/react-fontawesome
yarn add @fortawesome/fontawesome-free-regular @fortawesome/fontawesome-free-solid

Example code:

import fontawesome from '@fortawesome/fontawesome'
import FontAwesomeIcon from '@fortawesome/react-fontawesome'
import { faCircle as fasCircle } from '@fortawesome/fontawesome-free-solid'
import { faCircle as farCircle } from '@fortawesome/fontawesome-free-regular'

const Circle = ({ filled, onClick }) => {

  return (
    <div onClick={onClick} >
      <FontAwesomeIcon icon={filled ? farCircle : fasCircle}/>
    </div>
  );
};

class App extends React.Component {
  state = { filled: false };

  handleClick = () => {
    this.setState({ filled: !this.state.filled });
  };

  render() {
    return <Circle filled={this.state.filled} onClick={this.handleClick} />;
  }
}

See the github repo for more information: https://github.com/FortAwesome/react-fontawesome

This answer is an edited version of my answer here: How can I get Font Awesome 5 to work with React?.