首页 > 解决方案 > 用 React 组件替换子字符串

问题描述

我有一个通过 graphql 查询拉入的 HTML 内容块。在这个文本字符串中,我有表单中的“变量” %variable%。我需要用动态生成的内容替换变量。最简单的方法是将变量替换为 React 组件的输出。在这种情况下想要使用组件的原因是因为我需要从另一个来源获取数据来替换变量,并且数据会根据不同的输入而变化,所以我不能只是将字符串替换为字符串。

如果我这样做,content.replace("%variable%,<Component />)我会得到:

Lorem ipsum dolor sit amet, consectetur adipiscing elit。Donec vel lobortis massa。Fusce ac enim ullamcorper, vulputate diam ut, consequat diam。Duis ante odio, suscipit a rhoncus eget, sollicitudin vel nibh。Proin ut urna sed diam dictum commodo sed nec felis。在 hac habitasse platea dictumst 中。Vivamus varius nulla mi,[对象对象] convallis lorem aliquam ac。Quisque congue nibh sit amet nisl ultrices gravida。整数 ac lobortis nibh。Donec interdum placerat nibh,eget pharetra Tellus rut​​rum nec。In varius arcu eu luctus posuere。类 aptent taciti socialsqu ad litora torquent per conubia nostra, per inceptos himenaeos。Aenean porttitor orci et eros auctor,在 porta dui bibendum。Donec sed consequat felis。

所以,%variable正在被取代[Object object]- 不是我希望的......

我查看了对类似查询的其他一些回复,但看不到适用于这种情况的解决方案。

这可能吗?

标签: reactjs

解决方案


这是一种可能的方法。split模板的内容%variable%。迭代结果,用于map渲染每个部分。对于每次迭代,也渲染<Component />.

像这样:

import React from "react";
import "./styles.css";

const getContent = () =>
  "Lorem ipsum dolor sit amet %variable% Proin ut urna sed diam %variable% per inceptos himenaeos";

const Component = () => (
  <span style={{ color: "red" }}>I'm actually Component</span>
);

export default function App() {
  const [content, setContent] = React.useState([]);
  React.useEffect(() => {
    setContent(getContent().split("%variable%"));
  }, []);
  return (
    <div className="App">
      {content.map((child, i) => (
        <>
          {child}
          {i < content.length && <Component />}
        </>
      ))}
    </div>
  );
}

更新

为了支持不同的变量,请使用split正则表达式而不是纯字符串。第二部分是在变量名称和等效组件之间保存一个映射器,并在渲染时检查当前项目是否是变量(startsWith('%'))渲染等效组件,否则渲染项目(这是原始字符串的下一个)

import React from "react";
import "./styles.css";

const getContent = () =>
  "Lorem ipsum dolor sit amet %variable% Proin ut urna sed diam %variable1% per inceptos himenaeos";

const Component = () => (
  <span style={{ color: "red" }}>I'm actually Component </span>
);

const Component1 = () => (
  <span style={{ color: "green" }}>I'm actually Component </span>
);

const mapper = {
  "%variable%": <Component />,
  "%variable1%": <Component1 />
};

export default function App() {
  const [content, setContent] = React.useState([]);
  React.useEffect(() => {
    setContent(getContent().split(/(%.*?% )/g));
  }, []);
  return (
    <div className="App">
      {content.map(child => (
        <>{child.startsWith("%") ? mapper[child.trim()] : child}</>
      ))}
    </div>
  );
}

https://codesandbox.io/s/gracious-panini-yylug?file=/src/App.js


推荐阅读