11

我正在尝试通过单击待办事项列表项来切换 Font Awesome 图标。这是整个组件...

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;

这是我的 FA 5 CDN(直接来自网站)...

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

我已经截取了一些 React 开发工具和检查器的屏幕截图......

这是不完整的 React 组件(默认) 不完整时反应组件

在完成的同时... 完成时反应组件

检查器中的两个图标元素,我注意到默认情况下未使用的元素被注释掉了。 在此处输入图像描述

如您所见,我可以在 React 工具中手动切换完整状态和组件更改,但不会呈现更改。我更改了默认状态以确保两个图标都正确加载并且它们是正确的。我制作了一个Codepen以在不同的环境中尝试它,这个可以工作,但我使用的是 FA 4.7.0 CDN。使用 Codepen 和 FA 4.7.0,当我检查图标时,它只是一个 HTML 元素而不是 SVG。

我想让这个组件与 FA 5 一起工作,所以任何帮助都将不胜感激!

4

6 回答 6

18

font-awesome javascript 不会在 React 重新渲染触发器上重新渲染。如果您可以不使用新的 font-awesome svg/javascript 图标,您可以使用 font-awesome 作为带有 css 的 webfont。

在您的 index.html 中,删除 fontawesome 脚本,并添加 font-awesome css 样式表:

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

您的代码现在应该可以工作了。


另一种可能性是使用官方的 font-awesome react 包(这有点麻烦,但它使用了新的 svg 图标)

将必要的包添加到项目中:

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

示例代码:

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} />;
  }
}

有关更多信息,请参阅 github 存储库:https ://github.com/FortAwesome/react-fontawesome

这个答案是我的答案的编辑版本:如何让 Font Awesome 5 与 React 一起使用?.

于 2017-12-24T17:23:09.553 回答
14

由于 FA 5 将 svg 元素注入 DOM,它可能无法很好地与 React 的虚拟 DOM 配合使用。希望这是他们会解决的问题,但一个简单的解决方法是只包含两个图标而不是切换它们,并通过将其中一个或另一个包装在应用的容器中来隐藏它display: none。例如:

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>
  )
}
于 2017-12-23T03:43:45.360 回答
2

今天我的 ReactJS/Material-UI 应用程序也遇到了同样的问题。经过大量研究,我通过使用 React 的key属性解决了这个问题,该属性会在其关联状态更改时强制元素呈现。

所以,在这个例子中,我将重写渲染方法如下:

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>
    );
  }

在这里,我将this.state.complete其用作唯一值,key但你可以使用任何你喜欢的东西,只要它们是唯一的。

现在,span元素总是在重新渲染时被移除并被另一个元素替换。

希望这个答案对未来的求职者有所帮助。

于 2018-09-06T13:04:16.620 回答
2

看起来另一个修复方法是window.FontAwesomeConfig = { autoReplaceSvg: 'nest' }在加载 FA JavaScript 之后在应用程序的启动周期中调用某个位置。

另请参阅https://stackoverflow.com/a/48552226/53790https://fontawesome.com/how-to-use/svg-with-js#auto-replace-svg-nest

于 2018-05-24T21:15:13.143 回答
1

根据上面的讨论,这可能是一个很棒的错误,而不是反应错误

于 2017-12-08T04:20:26.027 回答
0

您可以使用 to function 而不是 class 但在此之前您需要为 reactjs 代码下载 react fontawesome 包:

    import React from  'react';
    import Menuitems from '././Menuitems';
    import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
    import { faTimes, faBars } from '@fortawesome/free-solid-svg-icons';
    
    const Menu =() => {
    
       const [item, setItem]= React.useState(false);
    
       const handleitem =()=>{
         setItem(!true);
       }
        return(
            <>
              <Container>
                  <nav>
                       <h1> react </h1>
                 
                     <div className="menu-icon" onClick={handleitem}>
                        <FontAwesomeIcon icon={item ? faTimes :  faBars } size="3x"/>
                     </div>
                  </nav>
               </Container>
            </>
        );
    }
    
    export default Menu;
于 2020-11-29T15:29:54.197 回答