[英]Toggling Font Awesome 5 icon with React
我试图通过单击待办事项列表项来切换 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 工具中手动切换完整状态和组件更改,但不会呈现更改。 我更改了默认状态以确保两个图标都正确加载。 我制作了一个Codepen来在不同的环境中尝试它,这个可以工作,但我使用的是 FA 4.7.0 CDN。 使用 Codepen 和 FA 4.7.0,当我检查图标时,它只是一个 HTML 元素而不是 SVG。
我想让这个组件与 FA 5 一起工作,所以任何帮助将不胜感激!
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
这个答案是我在此处的答案的编辑版本: How can I get Font Awesome 5 to work with 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>
)
}
看起来另一个修复方法是在加载 FA JavaScript 后,在应用程序的启动周期中的某个位置调用window.FontAwesomeConfig = { autoReplaceSvg: 'nest' }
。
另见https://stackoverflow.com/a/48552226/53790和https://fontawesome.com/how-to-use/svg-with-js#auto-replace-svg-nest 。
今天我的 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
元素总是在重新渲染时被移除并被另一个元素替换。
希望这个答案可以帮助未来的寻求者。
根据上面的讨论,这可能是一个很棒的错误,而不是反应错误
您可以使用 to 函数而不是类,但在此之前您需要下载 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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.