我正在使用从WordPress API获取数据的Node.js / React.js客户端,而且我遇到了相当棘手的问题。但希望你可以帮助我! :)
所以我把这种数据作为WordPress API(单页内容)中的字符串:
"<h1>Curabitur turpis.</h1>
<p>Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Praesent blandit laoreet nibh. Aenean commodo ligula eget dolor. Donec vitae sapien ut libero venenatis faucibus.</p>
[gravityform id=”42″ title=”true” description=”true”]
<h2>Donec vitae orci sed</h2>
<p><strong>Suspendisse faucibus</strong>, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi.</p>
<blockquote><p>Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Aliquam lobortis. In turpis.</p></blockquote>
<ul><li>item</li><li>item</li><li>item</li></ul>"
我需要做的是将短代码[gravityform id=”42″ title=”true” description=”true”]
替换为React组件<GravityForm />
和想要的事件处理程序等,并按原样渲染其他html元素。
我正在做替换,如:
export const replaceGravityFormShortcode = html => {
if(!html) return html;
const gravityFormRegexp = /\[gravityform id=.([0-9]{1,}).*?\]/g;
return replace(
html,
gravityFormRegexp,
function (fullMatch, id) {
return <GravityForm key={id} formId={id} />;
}
);
};
因此,已经涵盖了用React组件替换[shortcodes],但之后html数据如下所示:
[
0:"<h1>Curabitur turpis.</h1><p>Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Praesent blandit laoreet nibh. Aenean commodo ligula eget dolor. Donec vitae sapien ut libero venenatis faucibus.</p>"
1:Object (GravityForm-component)
2:"<h2>Donec vitae orci sed</h2><p><strong>Suspendisse faucibus</strong>, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi.</p><blockquote><p>Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Aliquam lobortis. In turpis.</p></blockquote><ul><li>item</li><li>item</li><li>item</li></ul>"
]
很明显,因为
而无法在render()
内工作
dangerouslySetInnerHTML
,它看起来像这样(<GravityForm />
是[object Object]
)dangerouslySetInnerHTML-screenshot 对于这个问题,有没有合理的解决方案?或者应该从不同的角度来看待它?
感谢您的帮助!
@joy是的,您的解决方案是将html字符串更改为React Components,但它仍然无法解决html转义问题。所以我仍然有像(screenshot)
这样的输出<h1>Curabitur turpis.</h1><p>Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Praesent blandit laoreet nibh. Aenean commodo ligula eget dolor. Donec vitae sapien ut libero venenatis faucibus.</p>
<h2>Donec vitae orci sed</h2><p><strong>Suspendisse faucibus</strong>, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi.</p><blockquote><p>Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Aliquam lobortis. In turpis.</p></blockquote><ul><li>item</li><li>item</li><li>item</li></ul>
但是,甚至可以在不从字符串中逐个解析html元素的情况下渲染该html吗?
所以我终于找到了〜解决这个案例的方法。
[
0:Object
1:Object
2:"[gravityform id=”42″ title=”true” description=”true”]"
3:Object
4:Object
5:Object
6:Object
]
replaceGravityFormShortcodesFromArrayOfObjects(arrayOfObjects)
,将[gravityform id=”42″ title=”true” description=”true”]
替换为<GravityForm />
,然后只渲染数据export const replaceGravityFormShortcodesFromArrayOfObjects =(dataArray) => {
if(!dataArray) return dataArray;
const gravityFormRegexp = /\[gravityform id=.([0-9]{1,}).*?\]/g;
forEach(dataArray, (value, index) => {
if(typeof value === 'string'){
const temp = replace(
value,
gravityFormRegexp,
function (fullMatch, id) {
return <GravityForm key={id} formId={id} />;
}
);
if(temp.length === 1 && isObject(temp[0])){
dataArray = [
...dataArray.slice(0, index),
temp[0],
...dataArray.slice(index + 1),
];
}
}
}
return dataArray;
};
但是只有在html结构深度为一级时才有效。如果"[gravityform id=”42″ title=”true” description=”true”]"
位于React元素props.children
中,那么它会变得棘手,我还没有找到可行的解决方案。
答案 0 :(得分:0)
我遇到了完全相同的问题,这是我的解决方案:
定义字符串:
const s = `<h1>Curabitur turpis.</h1>
<p>Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Praesent blandit laoreet nibh. Aenean commodo ligula eget dolor. Donec vitae sapien ut libero venenatis faucibus.</p>
[gravityform id=”42″ title=”true” description=”true”]
<h2>Donec vitae orci sed</h2>
<p><strong>Suspendisse faucibus</strong>, nunc et pellentesque egestas, lacus ante convallis tellus, vitae iaculis lacus elit id tortor. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi.</p>
<blockquote><p>Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Aliquam lobortis. In turpis.</p></blockquote>
<ul><li>item</li><li>item</li><li>item</li></ul>`
按[*]
分割字符串:
const normalText = s.split(/\[[\s\S]+\]/g)
提取ID:
let ids = [];
const re = /\[gravityform id=.*([0-9]{1,}).*\]/g;
s.replace(re, (fullMatch, id) => {
ids.push(id)
})
现在,数组normalText
和ids
具有我们想要连接的内容。简单地说吧:
const output = normalText.map((text, index) => {
<div>
{text}
<GravityForm key={ids[index]} formId={ids[index]} />
</div>
})
// Then put `output` in the `render` function
您可能希望稍微调整正则表达式,因为您的字符串包含一些像”
这样的unicode。要么先移除它们,要么先逃脱它们。
为了不逃避HTML:
<div dangerouslySetInnerHTML={{ __html: text }}/>