用 React 组件替换部分字符串

时间:2021-02-22 17:20:11

标签: javascript reactjs

我在这里看到了这个问题,但似乎没有一个答案是真正的组件或没有奏效,所以我要发布我的问题,看看我是否遗漏了什么。

我正在制作一个包含正文部分的博客,用于添加故事。我想在正文中有一组特殊的字符 '{{21}}' 以指示它应该替换为 PhotoDeck 组件并传入列表 21 中的照片。在我的 API 中,我能够解析文本,查找标记,获取 id,并将其作为对象数组添加到 api 返回:

inline_photos": [
{
"list_id": "21",
  "photos": [
    "/img/ODdiNzUwODMtZTBiZi00MTE2LTg1NjEtYTkyYjU3OWUyNzQxLmpwZw20210127010134.jpeg",
    "/img/YmFsaS5wbmc20210127010135.png"
  ]
},
{
"list_id": "22",
  "photos": [
    "/img/MDFfRXVyb3BlLmpwZw20210222030245.jpeg",
    "/img/ZGVhYWM5OWRfb3JpZ2luYWwuanBn20210222030246.jpeg"
  ]
}
]

在我显示页面的反应组件中,我正在导入接收“照片”道具的 PhotoDeck 组件;

我将主体传递给一个函数,我希望它循环遍历 inline_photos 数组,并用组件和内联数组中的照片替换字符串中的 {{21}} 和 {{22}}。

我的想法是这样的:

const get_inline = body => {
    if(post.inline_photos.length){
      post.inline_photos.map( list => {
          body = body.replace(`{{${list.list_id}}}`,<PhotoDeck photos={list.photos} />);
      })
    }else{
      return body;
    }
  }

正如预期的那样,由于组件在替换时呈现为字符串,因此它返回 [Object, Object]。我已经看到许多正则表达式库作为解决方案发布,但对我来说问题不是找到要替换的标记,而是实际“插入”一个组件来代替它。

<h2>Why Bali?</h2><p>[object Object]Twenty-two hours in-flight (from Toronto) and fifteen hours in layovers later, we found ourselves in a dream of a location, Bali. We could not have picked a better destination to spend our honeymoon in. When we were researching where to celebrate our marriage, we wanted to go somewhere special, where we could be both adventurous and lazy bums, without breaking bank.&nbsp;</p>

这是实际正文的一小部分示例:

<h2>Why Bali?</h2><p>{{21}}Twenty-two hours in-flight (from Toronto) and fifteen hours in layovers later, we found ourselves in a dream of a location, Bali. We could not have picked a better destination to spend our honeymoon in. When we were researching where to celebrate our marriage, we wanted to go somewhere special, where we could be both adventurous and lazy bums, without breaking bank.&nbsp;</p>

能做到吗?谢谢!

//更新// 我使用了 react-string-replace 并且我没有在它生成的数组中得到它。是不是没有渲染完成的组件,有什么我没有做的吗?

$$typeof: Symbol(react.element)
key: null
props: {photos: Array(5)}
ref: null
type: ({ cards }) => {…}
_owner: FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
_store: {validated: false}
_self: undefined
_source: {fileName: "D:\src\components\postbody\PostBody.js", lineNumber: 19, columnNumber: 12}
__proto__: Object

2 个答案:

答案 0 :(得分:0)

我的意思是这样的:

body = list.list_id === 21 ? 
body.replace(`{{${list.list_id}}}`,<PhotoDeck photos={list.photos} />) 
: <PhotoDeck photos={list.photos} />

因为如果你想根据某种条件用整个组件替换某些东西,它需要是数字 21,我认为第一个地方是使用三元运算符,你把 ?和:

conditional (ternary) operator

“条件(三元)运算符是唯一采用三个操作数的 JavaScript 运算符:条件后跟问号 (?),然后是条件为真时执行的表达式,后跟冒号 (:),以及finally 条件为假时要执行的表达式。此运算符经常用作 if 语句的快捷方式。”

答案 1 :(得分:0)

好的,对我来说,解决方案是使用 react-string-replace (github.com/iansinnott/react-string-replace) 并传入标记并将其替换为组件。返回的是一个文本数组和我分配给“故事”状态的组件对象。

...
const [story, setStory] = useState([]);
...
    useEffect(() => {
        if(post.inline_photos.length){
          post.inline_photos.map( list => {
             post.body = reactStringReplace(post.body, `{{${list.list_id}}}`, (match, i) => (
               <div className="photo-deck-container"><div id="photo-deck"><PhotoDeck cards={list.photos} /></div></div>
              ));
          })
        }
        setStory(post.body);
        return;
      },[post])

(它在地图内,因为主体可以包含多个标记)

然后在故事中,我映射了值,如果它是一个对象,我将它打印到屏幕上,否则我将它传递给 ReactHtmlParser 以呈现 html 文本。

  { story.map( (piece,i) => {
            return typeof(piece)==='object' ? piece : ReactHtmlParser(piece)
  })}
相关问题