I have React component, where I have some dynamic text:
...
let spanLength
return(
<SomeComp>
...
<span>Some static text: {someDynamicText}, {someAnotherText}</span>
...
</SomeComp>
)
How can I get the length of text inside span element to a spanLength variable?
You can add a ref to your span
let spanRef = React.createRef()
...
<span ref={spanRef}>Some static text: {someDynamicText}, {someAnotherText}</span>
Then the text length would simply be spanRef.current.textContent.length
Why not, first, compose the whole string? You can grab its length immediately after, and then render it.
const spanStr = `Some static text: ${someDynamicText}, ${someAnotherText}`;
const spanLength = spanStr.length;
return(
<SomeComp>
...
<span>{spanStr}</span>
...
</SomeComp>
)
Related
I am working with styled components. I accept an h1 element as a prop from an object which contains a string called title. How can I insert a span element into the string of the object so I could style only this part separately as you would normally do if the text was hardcoded?
export const heroData = {
title: `Finance Data`,
You can use dangerouslySetInnerHTML attribute for adding raw HTML string to HTML.
export const heroData = {
title: "Finance <span style="color: red;">Data</span>"
... ...
<div dangerouslySetInnerHTML={{_html: heroData.title}} />
I've this text in string:
let text = "#Jim, Start editing to see some magic happen!";
how can I want to make it to?
text = "<span style="color:red">#Jim</span>, Start editing to see some magic happen!";
my failed attempt as below:
export default function App() {
let text = "#Jim, Start editing to see some magic happen!";
// const regex = /#|\[|\]/gm;
// text = text.replace(regex, (innerText) => {
// return <span style={{ color: "red" }}>{innerText}</span>;
// });
return (
<div className="App">
<div
dangerouslySetInnerHTML={{
__html: text
}}
/>
</div>
);
}
https://codesandbox.io/s/youthful-gwen-55757z?file=/src/App.js:24-419
I'm not sure this is what you really need. Anyway, I think it's a step closer.
I made a new regex to get '#' + words and for the text to be updated with replace it is necessary to play
text = text
Then:
import "./styles.css";
export default function App() {
let text = "#Jim, Start editing to see some magic happen!";
const regex = /\#[a-zA-Z]+/gm;
text = text.replace(regex, (match) => {
return `<span style="color: red">${match}</span>`;
});
return (
<div className="App">
<div
dangerouslySetInnerHTML={{
__html: text
}}
/>
</div>
);
}
Your approach works, its just that the style is not rendered in innerHTML
Run this example and you'll see that the hashtag appears bold (Also changed your regex a bit)
let text = '#Jim, Start editing to see some magic happen!';
const regex = /(#+[a-zA-Z0-9(_)]{1,})/gm;
text = text.replace(regex, (match) => {
return `<strong>${match}</strong>`;
});
If you want the styles to apply you have to change the Encapsulation in your component to None like so:
#Component({
selector: 'app-my-hashtag-component',
styles: ['./app-my-hashtag-component.css'],
templateUrl: './app-my-hashtag-component.html',
encapsulation: ViewEncapsulation.None,
})
I am trying to create a dynamic link Component that transforms a string in a string with a html anchor.
What I want to obtain is a component that returns this output:
<p>Do you want to search?</p>
I am passing this object to the component
let phrase = {
text : 'Do you want to search?'
linktext : 'to search',
linkurl : 'http://google.com'
}
This is the component I tried but do not work and the html is rendered as a text
function InfoLink(props) {
const q = props.phrase;
const link = "<a href={q.linkurl} >{q.linktext}</a>";
const text = q.text.replace(q.linktext, link);
return (
<p>{text}</p>
);
}
Is there a way to have a html output from the component by using replace?
You can split the text, and output the split text along with a react component for the anchor:
let phrase = {
text : 'Do you want to search?',
linktext : 'to search',
linkurl : 'http://google.com'
}
function InfoLink(props) {
const q = props.phrase;
const link = <a href={q.linkurl}>{q.linktext}</a>;
const [part1, part2] = q.text.split(q.linktext);
return (
<p>{part1}{link}{part2}</p>
);
}
ReactDOM.render(<InfoLink phrase={phrase}/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
You can split your sentence in 3 parts:
text_before_link <a href={q.linkurl}> text_with_link </a> text_after_link
Where...
text_before_link = q.text.substr(0,q.text.indexOf(q.linktext));
text_with_link = q.linktext;
text_after_link = q.text.substr(q.text.indexOf(q.linktext)+q.linktext.length);
Something like that.
The variable link is a JSX Object and you are adding it to an string. So the result will be something like: Do you want [Object][Object]. To solve this problem, you should split the string you want to show and the object and return both.
export default function App (props){
const q = props.phrase;
const link = <a href={q.linkurl}>{q.linktext}</a>;
const text = q.text.split(q.linktext)[0];
return (
<p>{text}{link}</p>
);}
Hope this can help.
I'm rendering some paragraphs using React. Inside those paragraphs there should be a span for footnotes. The best I got so far is that it rendered [object Object].
function ArticleItem() {
const articles = [
{
title: "title",
content: [
`Text based on this footnote <span>1</span>`,
`Another argument, here is my source <span>2</span>`
]
}
];
return (
<div className="article-container">
<h3> {articles[i].title} </h3>
{
articles[i].content.map(paragraph => (
<p>
{ paragraph }
</p>
)
}
</div>
);
}
Because you are creating a string with "<span>" instead of creating actual <span> HTML elements. What you are using is named jsx, which converts HTML tags to their corresponding document.createElement() (or similar, which in React has it own way).
If you want the content to be an HTML element and not a string, then create an HTML element:
function ArticleItem() {
const articles = [
{
title: "title",
content: [
<p>Text based on this footnote <span>1</span></p>,
<p>Another argument, here is my source <span>2</span></p>
]
}
];
return (
<div className="article-container">
<h3> {articles[i].title} </h3>
{ articles[i].content.map(paragraph => paragraph) }
</div>
);
}
Notice how I removed the string literal (``) and created an HTML element.
If the article content comes from an API call, then avoid using HTML tags inside strings. That's a bad practice actually. Always create the tags within the render() call and populate them with the API data you received.
Assuming the content array has to be supplied as raw HTML, a common solution is to use the dangerouslySetInnerHTML prop to render that HTML directly. You can introduce that to your <p> elements like this:
articles[i].content.map(paragraph => (
<p dangerouslySetInnerHTML={{ __html: paragraph }} />
))
A few other things to consider; I noticed a missing ) in your code after the <p> element of your map statement which will be causing a syntax error. Also, ensure that i is defined to an index in range of your articles array. Here's an example of each fix applied:
function ArticleItem() {
const articles = [
{
title: "title",
content: [
`Text based on this footnote <span>1</span>`,
`Another argument, here is my source <span>2</span>`
]
}
];
const i = 0;
return (
<div className="article-container">
<h3> {articles[i].title} </h3>
{
articles[i].content.map(paragraph =>
(<p dangerouslySetInnerHTML={{ __html: paragraph }} />)
)
}
</div>
);
}
Here's a working example as well - hope that helps!
I'm building a type ahead feature in React.
I have wrapper component that has an array of objects, and it renders item; which's a stateless component.
So, suppose I have const name= 'Hasan'. Which gets parsed to >> const parsedName = Ha<span>san</span>; assuming the term to search for is san.
I have tried dangerouslySetInnerHTML={{ __html: parsedName }} attribute on the parent element, but it didn't work.
With plain html this would be: el.innerHTML = parsedName
The goal is to style the span as desired. Any ideas?
class Test extends React.Component {
render() {
const name = 'san';
const parsedName = name.replace(new RegExp('san', 'ig'), '<span>span</span>');
return (
<div dangerouslySetInnerHTML={{__html: parsedName}}/>
);
}
}
ReactDOM.render(
<Test/>,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
</div>
Without code its hard to tell what's wrong. I have created a working snippet here that might help you debug your issue.
Updated the example based on the comment.