首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用React组件替换子字符串

用React组件替换子字符串
EN

Stack Overflow用户
提问于 2020-05-27 13:41:18
回答 2查看 349关注 0票数 2

我有一个HTML内容块,它是通过graphql查询拉进来的。在这个文本字符串中,我在表单%variable%中有“变量”。我需要用动态生成的内容替换变量。最简单的方法是将变量替换为React组件的输出。在本例中,希望使用组件的原因是,我需要从另一个源获取数据来替换变量,并且数据将根据不同的输入进行更改,因此不能只将字符串替换为string。

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

Lorem ipsum dolor坐好了,敬请光临。小龙虾马萨。[医]镰刀菌,外阴直径,其结果为.这是一首独唱,独唱。这是一种很好的方法。在hac栖息地高原上。 object lorem aliquam ac.奎斯克人坐在一起,怀孕了。整型腹膜炎。[医]穿山甲、金银花、金银花。在形形色色的地方。每一只夜蛾,每一只鸡,每只鸡。Aenean porttitor orci et eros拍卖师,在港口dui双轨。这是对非利士的惩罚。

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

我看过一些类似查询的其他响应,但实际上看不到适用于此实例的解决方案。

这个是可能的吗?

EN

回答 2

Stack Overflow用户

发布于 2020-05-27 14:19:01

这是一种可能的方法。split内容由模板%variable%。对结果进行迭代,使用map来呈现每个片段。对于每个迭代,还呈现<Component />

如下所示:

代码语言:javascript
复制
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和regex,而不是普通字符串。第二部分是在变量名和等效组件之间保存一个映射器,并在呈现时检查当前项是否是变量(startsWith('%'))呈现等效组件,否则呈现项(这是原始字符串的下一个部分)。

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2020-05-27 14:28:10

您可以使用ReactDOMServer.renderToStaticMarkupdangerouslySetInnerHTML的组合来处理您的情况。

工作代码演示

--基于注释编辑--对于多变量替换,维护变量和组件的映射,如代码片段和演示链接所示

代码片段

代码语言:javascript
复制
const Comp1 = () => (
  <div>
    dynamic component 1 <br />
  </div>
);
const Comp2 = () => (
  <div>
    dynamic component 2 <br />
  </div>
);
const Comp3 = () => (
  <div>
    dynamic component 3 <br />
  </div>
);

const variableToCompMapping = {
  "%variable1%": Comp1,
  "%variable2%": Comp2,
  "%variable3%": Comp3
};

export default function App() {
  const [content, setContent] = useState("");

  useEffect(() => {
    setContent(`
    lorem %variable1% ipsum 
    lorem %variable2% ipsum 
    lorem %variable3% ipsum 
    `);
  }, []);

  const renderContent = () => {
    let result = content;
    for (let dynamicVar in variableToCompMapping) {
      const compAsHtml = ReactDOMServer.renderToStaticMarkup(
        variableToCompMapping[dynamicVar]()
      );
      result = result.replace(dynamicVar, compAsHtml);
    }
    return result;
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <div
        className="content"
        dangerouslySetInnerHTML={{
          __html: renderContent()
        }}
      />
    </div>
  );
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62044558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档