You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中Font Awesome图标不随state更新变色问题

问题现象

开发随机名言展示应用时,需要让页面背景、「New Quote」按钮、Twitter分享图标同步显示随机生成的主题色。首次加载页面时Twitter图标颜色渲染正常,但点击「New Quote」按钮更新状态后,图标颜色始终停留在初始值,其余所有元素(包括专门添加的20×20px测试色块)都能正常切换颜色。

相关实现代码如下:

import React from 'react';
import './style.scss';
import randomColor from 'randomcolor';
import '@fortawesome/fontawesome-free/css/all.css';
import '@fortawesome/fontawesome-free/js/all.js';

const quotes = [
    'I do not fear computers. I fear lack of them.',
    'A computer once beat me at chess, but it was no match for me at kick boxing.',
    'Computer Science is no more about computers than astronomy is about telescopes.',
    'The computer was born to solve problems that did not exist before.',
    'Software is like entropy: It is difficult to grasp, weighs nothing, and obeys the Second Law of Thermodynamics; i.e., it always increases.',
    'Software is a gas; it expands to fill its container.',
    "All parts should go together without forcing.  You must remember that the parts you are reassembling were disassembled by you.  Therefore, if you can't get them together again, there must be a reason.  By all means, do not use a hammer.",
    "Standards are always out of date.  That's what makes them standards.",
    "Physics is the universe's operating system.",
    "It's hardware that makes a machine fast.  It's software that makes a fast machine slow.",
    'Imagination is more important than knowledge.  For knowledge is limited, whereas imagination embraces the entire world.',
    'The greatest enemy of knowledge is not ignorance, it is the illusion of knowledge.',
    'The more you know, the more you realize you know nothing.',
    'Tell me and I forget.  Teach me and I remember.  Involve me and I learn.',
    "Real knowledge is to know the extent of one's ignorance.",
    'If people never did silly things, nothing intelligent would ever get done.',
    'Getting information off the Internet is like taking a drink from a fire hydrant.',
    'If you think your users are idiots, only idiots will use it.',
    "From a programmer's point of view, the user is a peripheral that types when you issue a read request.",
    "Where is the 'any' key?",
    'Computers are good at following instructions, but not at reading your mind.',
    "There is only one problem with common sense; it's not very common.",
    'Your most unhappy customers are your greatest source of learning.',
    'Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.',
];
const authors = [
    '- Isaac Asimov',
    '- Emo Philips',
    '- Edsger W. Dijkstra',
    '- Bill Gates',
    '- Norman Augustine',
    '- Nathan Myhrvold',
    '- IBM Manual, 1925',
    '- Alan Bennett',
    '- Steven R Garman',
    '- Craig Bruce',
    '- Albert Einstein',
    '- Stephen Hawking',
    '- Socrates',
    '- Benjamin Franklin',
    '- Confucius',
    '- Ludwig Wittgenstein',
    '- Mitchell Kapor',
    '- Linus Torvalds',
    '- P. Williams',
    '- Homer Simpson, in response to the message, “Press any key”',
    '- Donald Knuth',
    '- Milt Bryce',
    '- Bill Gates',
    '- Donald E. Knuth',
];

const random = Math.floor(Math.random() * quotes.length);
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            quote: quotes[random],
            author: authors[random],
            color: randomColor(),
        };
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        const clickRandom = Math.floor(Math.random() * quotes.length);
        this.setState({
            quote: quotes[clickRandom],
            author: authors[clickRandom],
            color: randomColor(),
        });
    }

    render() {
        return (
            <div
                id="bg"
                style={{
                    backgroundColor: this.state.color,
                }}
            >
                <div id="quote-box">
                    <p id="text">{this.state.quote}</p>
                    <p id="author">{this.state.author}</p>
                    <a id="tweet-quote" href="https://twitter.com/intent/tweet">
                        <i
                            className="fa-brands fa-twitter-square fa-2xl"
                            style={{
                                color: this.state.color,
                            }}
                        ></i>
                    </a>
                    <div style={{
                        width: 20,
                        height: 20,
                        backgroundColor: this.state.color
                    }}></div>
                    <button
                        id="new-quote"
                        onClick={this.handleClick}
                        style={{
                            backgroundColor: this.state.color,
                            border: 'solid 1px ' + this.state.color,
                        }}
                    >
                        New Quote
                    </button>
                </div>
            </div>
        );
    }
}

export default App;
故障原因

问题出在同时引入了Font Awesome的CSS和JS资源:
引入的all.js会在页面加载后自动把写好的<i>图标标签替换为内置的<svg>元素,写在<i>标签上的内联color样式只在首次替换时生效,后续React状态更新触发重渲染时,样式绑定还在已经被替换移除的<i>标签上,没法同步到新生成的SVG图标上,所以颜色不会更新。其余元素都是React直接管控的原生DOM,样式能随状态正常同步。

修复方案

二选一即可:

  • 移除JS引入,只保留CSS版本。直接删除代码里的import '@fortawesome/fontawesome-free/js/all.js';这行,CSS模式下图标通过字体方式渲染,不会替换DOM标签,内联样式会持续生效,颜色切换恢复正常。
  • 如果需要保留SVG渲染模式,给图标标签添加绑定颜色值的key属性:
    <i
      key={this.state.color}
      className="fa-brands fa-twitter-square fa-2xl"
      style={{
          color: this.state.color,
      }}
    ></i>
    
    每次颜色变化时key值会同步改变,React会判定这是全新的元素重新渲染,Font Awesome的JS会重新生成对应颜色的SVG图标,也能解决问题。

内容的提问来源于stack exchange,提问作者Azeem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:57:20