尽管可能有多个匹配项,但如何仅从映射数据中动态渲染出一段内容?
How can I render out a piece of content dynamically only once from mapped through data, despite potentially multiple matches?
我有一个数据对象,我正在从 CMS 中提取数据以创建博客,并通过 content 对象进行映射以呈现博客的主体.
我创建了一个三元运算符,本质上是说,如果文本行的类型为 'strong',则将字体设为粗体,否则如果其类型为 'hyperlink',则使标签中的一段文字 link。
我遇到的问题是有些文本既是'bold'又是'hyperlinks',所以它把句子渲染了两次,我怎么能确保当类型是'bold' & 'hyperlink',它只渲染一次?
我的数据是这样的:
这里是我的文件,我在前端 return 这个数据:
<div className='text-left mt-12 text-white'>
<h1 className='text-5xl mb-4 font-header text-blue-500'>
{RichText.asText(data.title)}
</h1>
{data.content.map((t, i) => {
return (
<>
{!t.spans[0] && (
<p className={`text-lg mt-6 opacity-80 ${t.type}`}>
{t.text}
</p>
)}
{t.spans.map((item) =>
item.type === 'strong' ? (
<p className={`text-xl mt-6 font-bold ${t.type}`}>
{t.text}
</p>
) : item.type === 'hyperlink' ? (
<a
href={item.data.url}
target='_blank'
className={`text-lg opacity-80 mt-6 text-blue-500 ${t.type}`}>
{t.text}
</a>
) : item.type === 'list-item' ? (
<ul className='list-disc'>
<li className='text-lg mt-4 text-white'>{t.text}</li>
</ul>
) : (
<p
className={`text-lg opacity-80 mt-6 font-bold ${t.type}`}>
{t.text}
</p>
)
)}
</>
);
})}
</div>
我确定这很简单,但我想知道处理此类问题的最佳方法?
提前致谢!
不要在类型上进行逻辑切换。
尝试这样的事情:
const styleProps = spans.reduce((acc, span) => {
if (span === 'strong'){
acc['font-weight'] = 'bold';
}
if (span === 'something-else'){
acc['some-css-prop'] = 'some-value';
}
...
return acc;
}, {})
然后您将拥有一个累加器 (styleProps
),其中包含设置组件样式所需的所有必要道具。
<YourComponent className="my-constant-class-name" style={{...styleProps}} />
你可以概括这个想法:
例如
const MyComponentProps = spans.reduce((acc, span) => {
if (span === 'strong'){
acc.style['font-weight'] = 'bold';
}
if (span === 'hyperlink'){
acc['href'] = 'www.example.com';
}
...
return acc;
}, {});
还有
let MyComponent = null;
switch(type){
case 'hyperlink':
MyComponent = (props) => <a {...props} />;
break;
case 'text':
MyComponent = (props) => <p {...props} />;
break;
case 'bullet':
MyComponent = (props) => <li {...props} />;
break;
然后
<MyComponent {...MyComponentProps} />
我有一个数据对象,我正在从 CMS 中提取数据以创建博客,并通过 content 对象进行映射以呈现博客的主体.
我创建了一个三元运算符,本质上是说,如果文本行的类型为 'strong',则将字体设为粗体,否则如果其类型为 'hyperlink',则使标签中的一段文字 link。
我遇到的问题是有些文本既是'bold'又是'hyperlinks',所以它把句子渲染了两次,我怎么能确保当类型是'bold' & 'hyperlink',它只渲染一次?
我的数据是这样的:
这里是我的文件,我在前端 return 这个数据:
<div className='text-left mt-12 text-white'>
<h1 className='text-5xl mb-4 font-header text-blue-500'>
{RichText.asText(data.title)}
</h1>
{data.content.map((t, i) => {
return (
<>
{!t.spans[0] && (
<p className={`text-lg mt-6 opacity-80 ${t.type}`}>
{t.text}
</p>
)}
{t.spans.map((item) =>
item.type === 'strong' ? (
<p className={`text-xl mt-6 font-bold ${t.type}`}>
{t.text}
</p>
) : item.type === 'hyperlink' ? (
<a
href={item.data.url}
target='_blank'
className={`text-lg opacity-80 mt-6 text-blue-500 ${t.type}`}>
{t.text}
</a>
) : item.type === 'list-item' ? (
<ul className='list-disc'>
<li className='text-lg mt-4 text-white'>{t.text}</li>
</ul>
) : (
<p
className={`text-lg opacity-80 mt-6 font-bold ${t.type}`}>
{t.text}
</p>
)
)}
</>
);
})}
</div>
我确定这很简单,但我想知道处理此类问题的最佳方法?
提前致谢!
不要在类型上进行逻辑切换。
尝试这样的事情:
const styleProps = spans.reduce((acc, span) => {
if (span === 'strong'){
acc['font-weight'] = 'bold';
}
if (span === 'something-else'){
acc['some-css-prop'] = 'some-value';
}
...
return acc;
}, {})
然后您将拥有一个累加器 (styleProps
),其中包含设置组件样式所需的所有必要道具。
<YourComponent className="my-constant-class-name" style={{...styleProps}} />
你可以概括这个想法:
例如
const MyComponentProps = spans.reduce((acc, span) => {
if (span === 'strong'){
acc.style['font-weight'] = 'bold';
}
if (span === 'hyperlink'){
acc['href'] = 'www.example.com';
}
...
return acc;
}, {});
还有
let MyComponent = null;
switch(type){
case 'hyperlink':
MyComponent = (props) => <a {...props} />;
break;
case 'text':
MyComponent = (props) => <p {...props} />;
break;
case 'bullet':
MyComponent = (props) => <li {...props} />;
break;
然后
<MyComponent {...MyComponentProps} />