Javascript 使用React切换字体5图标

Javascript 使用React切换字体5图标,javascript,reactjs,font-awesome,font-awesome-5,Javascript,Reactjs,Font Awesome,Font Awesome 5,我试图通过点击待办事项列表项来切换字体图标。这是整个组件 import React from 'react'; import './TodoItem.scss'; class TodoItem extends React.Component { constructor(props) { super(props); this.state = { complete: false } this.toggleComplete = this.toggle

我试图通过点击待办事项列表项来切换字体图标。这是整个组件

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;
从“React”导入React;
导入“/TodoItem.scss”;
类TodoItem扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
完整:错误
}
this.toggleComplete=this.toggleComplete.bind(this);
}
toggleComplete(){
this.setState(prevState=>({
完成:!prevState.complete
}));
}
render(){
常数不完全图标=;
常数completeIcon=;
返回(
{this.state.complete?completeIcon:impleteIcon}
{this.props.item}
);
}
}
将默认值导出到doitem;
这是我的FA 5 CDN(直接来自网站)


我已经拍摄了一些React-dev工具和inspector的屏幕截图

以下是未完成时的React组件(默认值)

虽然完成了。。。

在inspector中的两个图标元素中,我注意到默认情况下未使用的元素被注释掉了。

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


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

根据上面的讨论,这可能是一个错误,而不是react错误

因为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>
  )
}
renderChatButton(){
常量未读=this.state.unread
常量法线图标=
常数未解释=
返回(
{normalIcon}
{unreadIcon}
)
}

字体可怕的javascript不会在React RERERERERENDER触发器上重新加载。如果不使用新的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">
示例代码:

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} />;
  }
}
从'@fortawesome/fontawesome'导入fontawesome'
从“@fortaweasome/react fontaweasome”导入Fontaweasome图标
从“@fortwome/fontwome free solid”导入{faCircle as fascrle}
从“@fortwome/fontwome free regular”导入{faCircle as farcycle}
常量圆=({filled,onClick})=>{
返回(
);
};
类应用程序扩展了React.Component{
状态={filled:false};
handleClick=()=>{
this.setState({filled:!this.state.filled});
};
render(){
返回;
}
}
有关更多信息,请参阅github回购协议:


这个答案是我在这里的答案的编辑版本:。

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


另请参见和。

我今天在使用ReactJS/Material UI应用程序时遇到了同样的问题。经过大量研究,我通过使用React的
属性修复了这个问题,该属性在元素的关联状态更改时强制元素进行渲染

因此,在本例中,我将重写渲染方法,如下所示:

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>
    );
  }
render(){
const icon=this.state.complete?():();
返回(
{icon}
{this.props.item}
);
}
在这里,我使用了
this.state.complete
作为
键的唯一值,但是只要它们是唯一的,您就可以使用任何您喜欢的值

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


希望此答案对未来的搜索者有所帮助。

您可以使用函数而不是类,但在此之前,您需要下载react-JS代码的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;
从“React”导入React;
从“/./Menuitems”导入菜单项;
从'@fortawesome/react fontawesome'导入{FontAwesomeIcon};
从“@fortawesome/free solid svg icons”导入{faTimes,faBars};
常量菜单=()=>{
const[item,setItem]=React.useState(false);
常量handleitem=()=>{
setItem(!true);
}
返回(
反应
);
}
导出默认菜单;

嗨,我把你的代码放进了一个代码笔,它似乎能工作。因此,很可能您有某种FA加载问题。@swyx自己刚刚尝试过,但似乎确实有FA问题,该代码在任何其他情况下都能正常工作。由于元素之间的唯一区别是类而不是内容,React是否可能不会呈现它?谢谢你的帮助,我不知道这是什么。不,你可以通过在这个类上放置任何其他具有某种样式的类来检查这是不是真的so@swyx是的,我没想到。哦,看,我们正在准备一个新版本的react Fontsome软件包,该软件包经过清理,更易于使用。预发行版已经发布,您可以在我们的开发分支中找到文档:不是bug。带有JS的SVG与虚拟DOM引擎不兼容。
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>
    );
  }
    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;