J'essaie de basculer une icône Font Awesome en cliquant sur un élément de la liste des tâches. Voici le composant entier ...
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;
Voici mon FA 5 CDN (directement du site) ...
<script defer src="https://use.fontawesome.com/releases/v5.0.1/js/all.js"></script>
J'ai pris quelques captures d'écran de l'outil de développement et de l'inspecteur de React ...
Voici le composant Réagir alors qu’il est incomplet (valeur par défaut)
Et les deux éléments d’icône de l’inspecteur, j’ai remarqué que celui qui n’était pas utilisé par défaut est commenté .
Comme vous pouvez le constater, je suis en mesure de basculer manuellement l'état complet et les modifications de composant dans l'outil Réagir, mais la modification n'est pas rendue. J'ai changé l'état par défaut pour m'assurer que les deux icônes sont chargées correctement. J'ai fait un Codepen pour l'essayer dans un environnement différent et celui-ci fonctionne, mais J'utilise le FA 4.7.0 CDN. Avec Codepen et FA 4.7.0, lorsque j'inspecte l'icône, il ne s'agit que d'un élément HTML et non de SVG.
J'aimerais que ce composant fonctionne avec FA 5, toute aide serait la bienvenue!
Le javascript font-awesome ne rend pas sur un déclencheur de réactif React. Si vous ne souhaitez pas utiliser les nouvelles icônes svg/javascript de font-awesome, vous pouvez utiliser font-awesome en tant que webfont avec css.
Dans votre index.html, supprimez le script fontawesome et ajoutez la feuille de style css font-awesome:
<link href="https://use.fontawesome.com/releases/v5.0.2/css/all.css" rel="stylesheet">
Votre code devrait fonctionner maintenant.
L'autre possibilité consiste à utiliser le paquetage officiel font-awesome react (c'est un peu plus compliqué, mais il utilise les nouvelles icônes svg)
Ajoutez les packages nécessaires au projet:
yarn add @fortawesome/fontawesome @fortawesome/react-fontawesome
yarn add @fortawesome/fontawesome-free-regular @fortawesome/fontawesome-free-solid
Exemple de 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} />;
}
}
Voir le repo de github pour plus d'informations: https://github.com/FortAwesome/react-fontawesome
Cette réponse est une version modifiée de ma réponse ici: Comment puis-je faire en sorte que Font Awesome 5 fonctionne avec React? .
Dans la mesure où FA 5 injecte des éléments svg dans le DOM, il ne fonctionne probablement pas bien avec le DOM virtuel de React. J'espère que c'est quelque chose qu'ils vont corriger, mais une solution de contournement simple consiste simplement à inclure les deux icônes au lieu de les basculer, et à masquer l'une ou l'autre en l'enveloppant dans un conteneur qui applique display: none
. Par exemple:
renderChatButton() {
const unread = this.state.unread
const normalIcon = <i className='far fa-comment' />
const unreadIcon = <i className='fas fa-comment' />
return (
<div className='header-button' onClick={ this.toggleChat }>
<span className={ unread ? 'hidden' : '' }>{ normalIcon }</span>
<span className={ unread ? '' : 'hidden' }>{ unreadIcon }</span>
</div>
)
}
Une autre solution consiste à appeler window.FontAwesomeConfig = { autoReplaceSvg: 'nest' }
quelque part dans le cycle de démarrage de votre application, après le chargement du code JavaScript FA.
Voir aussi https://stackoverflow.com/a/48552226/53790 et https://fontawesome.com/how-to-use/svg-with-js#auto-replace-svg-nest .
comme discuté ci-dessus c'est probablement un bug de fontawesome, pas un bug de réaction
J'ai rencontré le même problème aujourd'hui avec mon application ReactJS/Material-UI. Après de nombreuses recherches, j'ai résolu le problème en utilisant la propriété key
de React qui force le rendu d'un élément lorsque son état associé change.
Donc, dans cet exemple, je voudrais réécrire la méthode de rendu comme ci-dessous:
render() {
const icon = this.state.complete ? (<span key={this.state.complete} className="far fa-circle todo-item-icon"/>) : (<span key={this.state.complete} className="far fa-check-circle todo-item-icon"/>);
return (
<div className="todo-item" onClick={this.toggleComplete}>
{icon}
<span className="todo-item-text">{this.props.item}</span>
</div>
);
}
Ici, j’ai utilisé this.state.complete
comme valeur unique pour la key
, mais vous pouvez utiliser ce que vous voulez tant qu’ils sont uniques.
Maintenant, l'élément span
est toujours supprimé lors du rendu et remplacé par l'autre.
J'espère que cette réponse aide les futurs demandeurs.