首页 > 解决方案 > 如何将 React.Component 放入 CSS 内容属性(在 :before/:after 伪元素中)?

问题描述

styled-components中,我试图通过传递一个 React Icon 在悬停时渲染它,content但由于某种原因,我在悬停时的渲染是[Object Object].

零件:

export const FooLink = styled(Link)`
  padding: 0.5rem 2rem;
  color: ${({ theme }) => theme.colors.white};
  text-align: center;
  margin: 0 auto;
  position: relative;
  font-size: ${({ theme }) => theme.fontSizes.p};
  letter-spacing: 0.15em;
  transition: ${({ theme }) => theme.animations.trans3};

  &:after {
    content: '${FaArrowRight}';
    /* content: '>'; */
    position: absolute;
    opacity: 0;
    right: -${({ theme }) => theme.spacings.small};
    transition: ${({ theme }) => theme.animations.trans3};
  }

  &:hover {
    padding-right: ${({ theme }) => theme.spacings.small};
    padding-left: ${({ theme }) => theme.spacings.xxSmall};
  }

  &:hover:after {
    opacity: 1;
    ${({ theme }) => theme.spacings.xSmall};
  }
`

我把所有东西都带进来了:

import styled from 'styled-components'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

其他内容尝试

content: ${FaArrowRight};

但我发现这不起作用:

那是因为内容值必须在 CSS 中的引号内。

意识到我可能在 CSS 心理状态中花费了太长时间,我尝试引入 React:

import React from 'react'
import styled from 'styled-components'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

和渲染:

content: '${(<FaArrowRight />)}';

当我尝试使用模板文字时,我收到缺少分号的错误:

content: `'${<FaArrowRight />}'`;

所有尝试都呈现为[Object Object]

研究看看是否有人问过这个问题,我已经通读了:

styled-components如何在中渲染 React 图标content

标签: javascriptcssreactjsstyled-componentsreact-component

解决方案


如果您需要将styled-components(或任何其他 CSS-in-JS 库)与来自react-icons(或任何其他导出React.Component呈现<svg>元素的库)中的图标一起使用,我看到唯一的一种方法:将组件转换为url()带有标记的字符串,因为只有这样你才能content在你的情况下将图像传递给属性。对于该转换,您需要React.createElement()ReactDOMServer.renderToStaticMarkup()encodeURIComponent()。此外,您可以改用Base64

这个有效(CodeSandbox):

import { createElement } from "react";
import { render } from "react-dom";
import { renderToStaticMarkup } from "react-dom/server";
import styled from "styled-components";
import { Link } from "gatsby";
import { FaArrowRight } from "react-icons/fa";

window.___loader = { enqueue: () => {}, hovering: () => {} };

const reactSvgComponentToMarkupString = (Component, props) =>
  `data:image/svg+xml,${encodeURIComponent(
    renderToStaticMarkup(createElement(Component, props))
  )}`;

const FooLink = styled(Link)`
  ${({ color }) => color && `color: ${color};`}
  &:after {
    content: ${({ color }) =>
      `url(${reactSvgComponentToMarkupString(FaArrowRight, {
        color
      })})`};
    position: absolute;
    opacity: 0;
  }

  &:hover:after {
    opacity: 1;
  }
`;

render(
  <>
    <div>
      <FooLink to="/test1" color="red">
        Link with arrow (red)
      </FooLink>
    </div>
    <div>
      <FooLink to="/test2">Link with arrow (default)</FooLink>
    </div>
  </>,
  document.getElementById("root")
);

感谢这个 Github Gist


推荐阅读