Why does react not compile HTML present in a state - html

I set a default value of a state to be <b> Hey </b> . Now when I rendered this state on the UI it printed the string instead of Hey wrote in bold.I want to know why it is not working. Why react is not able to interpret the html tag and show the appropriate output
import { useState } from "react";
import "./styles.css";
export default function App() {
const [html, setHtml] = useState("<b>Hey</b>");
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>{html}</div>
</div>
);
}
Output :-
Was expecting the output to be Hey written in bold.
Here's the codesandbox link for better understanding :- https://codesandbox.io/s/heuristic-chaum-vo6qt?file=/src/App.js
Thank you. I just want to know why react is not able to render the HTML tag as HTML tag instead of printing it out.

Because you are rendering a string, not HTML. If you want to render stringified HTML then use dangerouslySetInnerHTML, use caution what you pass through, in other words, you may want to run the string through a DOM purifier first.
export default function App() {
const [html, setHtml] = useState("<b>Hey</b>");
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div dangerouslySetInnerHTML={{ __html: html}} />
</div>
);
}

You are setting the value of html as "<b>Hey</b>" which is a string string that's why it renders that as it is. You can directly assign html to the variable like so:
const [html, setHtml] = useState(<b>Hey</b>);

It's a string and not HTML, to fix that maybe you can insert it in the div as innerHTML ie.
document.querySelector(".divClassName").innerHTML = html

Related

how can I use useRef to treat the div as textarea

I have a long message saved as html format. I want to show this message to the screen without Html element as textarea input.
message = <p>Mobil &auml ........ </p>
Before I upgrade React version to V6 it was working fine as the code below.
I could scroll down and adjust the textarea box size to see the message inside the box.
<div
id="textarea"
name="message"
className="form-control"
dangerouslySetInnerHTML={{__html: this.state.message }}
ref="textarea"
/>
after updating to React V6, when I write exactly the same code, it gives me an error saying
"Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here".
My first approach was to just simply delete ref="textarea" but then the message is overflow from the box and cannot read other information below.
And my second approach is to use useRef() but im not really understanding how to incorporate it to my code.
any suggestion here plz.
First option:
import { useEffect, useRef } from 'react';
function Teste() {
const divElement = useRef<HTMLDivElement>(null);
useEffect(() => {
if (divElement.current) {
divElement.current.appendChild(document.createElement('textarea')).value = 'Hello World';
}
});
return <div ref={divElement} />;
}
export default Teste;
Second option:
https://www.radix-ui.com/docs/primitives/utilities/slot

HTML not rendered inside tooltip from react-tooltip

I used tooltip form react-tooltip and I want to inside tooltip put some HTML tags. How to manage this? I don't find any information in react-tooltip site.
For now I create Tooltip:
const TooltipConst = props => {
if (props.tooltip && props.id) {
const tooltip = <Tooltip id={props.id + 'Tooltip'}>
<div> render(){props.tooltip} </div>
</Tooltip>;
return (
<OverlayTrigger
overlay={tooltip}
placement="top"
delayShow={500}
delayHide={1000}
>
{props.children}
</OverlayTrigger>
);
}
return <div>{props.children}</div>;
};
And when pass as tooltip some string with HTML they not rendered. Any advice?
I try also put as object, for example <span><p>some text</p> Some text </span>, but it return not text but something like Object[] as tooltip.
If you want to add html in ReactTooltip, like html button or other html tags in it. And wants to show on click.
<div id={row.index} className="text-center">
<a data-tip={'dummystring'} data-event={'click focus'}
data-for={'tooltip'}>Show tooltip</a>
<ReactTooltip id={'tooltip'} effect="solid"
clickable={true} place="right"
getContent={function() {
return (
<div>
<span>Some text</span>
<Button
onClick={()=>alert('clicked')}>
Click Me </Button>
</div>
)
}}/>
</div>
const tooltip = (<Tooltip id={props.id + 'Tooltip'}>
<div> render(){props.tooltip} </div>
</Tooltip>);
this is by their officiel documentation
also if you want to render html through props you should use dangerouslySetHTML => see React's documentation
You can use react-tooltip library.
Pass a prop html={true} to <ReactTooltip /> as <ReactTooltip html={true} /> for more information refer this link
This is an old question but I had a look into the documentation and they now have a data-html prop to detect if you want render html markup, something like this:
<ToolTipData data-tip={text} data-html={text.indexOf('</') > -1}>
{children}
</ToolTipData>
It's not super obvious from the docs but even if you are wanting HTML to be rendered inside the tooltip, it still needs to be in a string (wrap your HTML in backticks). Setting the html prop on the tooltip under the hood sets dangerouslySetInnerHtml on the string you pass in.
const inner = `<p>I'm html in a string</p><p>Same</p>`
and your tooltip:
<ReactTooltip
html={true}
id={"tooltip"}
place="right"
type="dark"
effect="solid"
>
{inner}
</ReactTooltip>

reactjs dangerouslySetInnerHTML and dynamically adding classes to links

I'm new to reactjs and working on a project that is pushing json data to the template.
json structure
"description" : "Some text with a link and another link",
I propose using the following on the template
<p className='paragraph-margin-bottom-10 text--font-size-14 paragraph--justified' dangerouslySetInnerHTML={{ __html: lang.privacy[0].description }} />
but in terms of the output - I would maybe need to append a set of classes to ALL links. What is the best practice for this
so the links render with the following
<a class="text--font-size-14 hyperlink-primary" href="#">link</a>
I can imagine that many people will not agree with me. You can actually do this. But you shouldn't. It is bad enough that you want to use dangerouslySetInnerHTML. It is possible to parse html but there are many edge cases that you would need to handle.
Either tell your backend that they should return the links with proper classes or target the links inside the description directly with css.
See some similar question like: Using regular expressions to parse HTML: why not?
Using regular expressions to parse HTML: why not?
This is how I would do it. I will write the regex later if you run into some problems. I don't have much time to spare right now. Hope it will help. :)
import React from 'react';
import { render } from 'react-dom';
const htmlFromApi = 'some html from API'
const attachClassesToLinks = (htmlWithLinks) => {
// do something special
return htmlWithLinks
}
const App = () => (
<div>
<h1>My Component</h1>
<p dangerouslySetInnerHTML={{ __html: attachClassesToLinks(htmlFromApi) }} />
</div>
);
render(<App />, document.getElementById('root'));

Reactjs: How to put HTML into primaryText of a list item?

I would like to have a span inside the ListItem like this:
<ListItem
primaryText={"<span class='inner'>Some important info</span>" + item.title}
/>
When this is rendered, I don't get an HTML span element, but a text <span class='inner'>Some important info</span>Title of the list item. How to make HTML render as HTML?
Remove "" around the span, because when you use " it will get converted into string, it will not be treated as html tag.
Write it like this this:
primaryText={<div>
<span className='inner'>Some important info</span>
{item.title}
</div>}
Note: class is reserved keyword so, to apply css classes use className.
EDIT: Ignore me, just saw you needed it specifically for a ListItem
If you need to render HTML within an element, you can use the dangerouslySetInnerHTML prop (but it comes with some risks, and the name suggests):
function createMarkup() {
return {__html: 'First ยท Second'};
}
function MyComponent() {
return <div dangerouslySetInnerHTML={createMarkup()} />;
}
Docs here:
https://facebook.github.io/react/docs/dom-elements.html#dangerouslysetinnerhtml
Based on the info given, you should move the span inside the ListItem component and deal with it there rather than passing in the props.
<ListItem
primaryText={ 'Some important info' }
title={ item.title }
/>
//List Item Component
import React from 'react'
const ListItem = ( props ) => {
return (
<li>
<span className='inner'>{ props.primaryText }</span>{ ` ${props.title}` }
</li>
)
}
export default ListItem

How to get the HTML output from a rendered component

I am a newbie to the ReactJS world and trying to get into it. I am working on a style guide for which I need to display some HTML code as an example. I am using ReactPrism for that and I am not able to get the HTML output inside my PrismCode component, I have find a work around by using react-to-jsx which shows the JSX code instead of HTML.
This is the code:
import React from 'react';
import {PrismCode} from "react-prism";
import reactToJsx from 'react-to-jsx';
class CodePreview extends React.Component {
render (){
return (
<div>
{this.props.children}
<h5>Code example</h5>
<pre>
<PrismCode className="language-javascript">
{reactToJsx(this.props.children)}
</PrismCode>
</pre>
</div>
);
}
}
export default CodePreview;
So basically I want to render this.props.children (the component) as HTML code and not the content of it in the PrismCode
I even tried the following as shown on https://github.com/tomchentw/react-prism, but it doesn't work. Not sure what I am doing wrong!
<PrismCode className="language-javascript">
{require("raw-loader!./PrismCode")}
</PrismCode>
Have you considered writing your docs in markdown? I added some special tags for react:
```react:mirror
<Slider
value={7}
/>
```
This will show the rendered component and also the JSX syntax highlighted.
```react:demo
<PropsEditor>
<Slider
value={7}
/>
</PropsEditor>
```
This will render the component as well as a live editor to manipulate any props on the component.
```react
<SomeComponent />
```
Will just syntax highlight but not render the component.
At the top of my markdown file I can import any components I am using in the doc:
---
imports:
- import Slider from '../src/slider'
- import PropsEditor from 'props-editor'
---
The advantage of this way is that your docs work as normal markdown and it's easy to get the JSX as you have it as a string.
To get the HTML source I have a "View Source </> button which prints formatted html dynamically when clicked:
The steps are:
on click get the html of the react component
format the html using prism and a beautifier
insert it into the DOM
So wrap your react component and make a reference to the node:
<div ref={(n) => (this.fenceView = n)}>
And on click add the output below the component, relevant bits:
import prismjs from 'prismjs';
import beautify from 'xml-beautifier';
const RE_HTML_COMMENTS = /<!--[\s\S]*?-->/g;
removeCodeSource() {
const existingHtmlCode = this.fenceView.querySelector('.fence-generated-html');
if (existingHtmlCode) existingHtmlCode.remove();
}
renderCodeSource() {
const html = this.fenceView.children[0].innerHTML.replace(RE_HTML_COMMENTS, '');
const fenceCode = beautify(html, ' ');
const highlightedCode = prismjs.highlight(fenceCode, prismjs.languages.html);
this.removeCodeSource();
this.fenceView.insertAdjacentHTML('beforeend',
`<pre class="fence-generated-html language-html"><code>${highlightedCode}</code></pre>`);
}