let htmlFromBackend = `Some backend HTML in table format`
return (
<div dangerouslySetInnerHTML={{ __html: htmlFromBackend}}></div>
)
I want to add some buttons(I want to add a button in every <tr></tr>) and elements in the html getting from backend. How it can be acheived?
For the simplest solution, you can prepend the HTML directly. For example:
return (
<div dangerouslySetInnerHTML={{ __html: `<button onclick="alert('Nice!')">Alert</button>${htmlFromBackend}`}}></div>
)
To prepend buttons on multiple elements of the HTML, you can either use RegExp or parse it first. I'll show you an example that parses the HTML first and edit it.
function preprocessHTML(html){
const element=document.createElement('div');
element.innerHTML=html;
// do any operations you like, for example:
for(const child of element.children){
const btn=document.createElement('button');
btn.innerText='Click Me!';
child.prepend(btn);
}
return element.innerHTML;
}
return (
<div dangerouslySetInnerHTML={{ __html: preprocessHTML(htmlFromBackend)}}></div>
)
If you want to prepend with React, you can use ReactDOM.createPortal to render any JSX element to any HTMLDom.
Hello I am working on a blog post creation tool and I need a engine when I write in textarea <hr/> I get a line, or when I write <img/> I get an image but it doesn't render.
The post is written in a textarea and should be displayed in a div.
How to do it?
const PostCreate = () => {
const [postValue, changeValue] = useState('')
const handleChangeValue = (e:any) => {
changeValue(e.target.value)
console.log(postValue);
}
return (
<div className='postCreate'>
Create New Post
<textarea onChange={handleChangeValue} value={postValue}/>
<div>
{postValue}
</div>
</div>
)
}
If I write <hr/> I get the string <hr/> instead of a line:
You can use dangerouslySetInnerHTML prop for the div.
<div dangerouslySetInnerHTML={{ __html: postValue }} />
You can check it on this document.
I have this string:
export default function App() {
const string = 'test data,cars,colors,demo';
return (
<div className="App">
<h1>Hello {string.replaceAll(',','<br>')}</h1>
</div>
);
}
I expect:
test data<br>cars<br>colors<br>demo
But i get one string without breack inside my string. How to achieve what i expect using replaceAll()?
In order to display html from string you have to use dangerouslySetInnerHTML
export default function App() {
const string = 'test data,cars,colors,demo';
return (
<div className="App">
<h1 dangerouslySetInnerHTML={{ __html: `Hello ${string.replaceAll(',','<br>')}`}}></h1>
</div>
);
}
Assuming this is a React application you need to use dangerouslySetInnerHTML to add the new HTML to the page.
function Example() {
const string = 'test data,cars,colors,demo';
const html = `Hello ${string.replaceAll(',', '<br>')}</h1>`;
return (
<div className="App">
<h1 dangerouslySetInnerHTML={{ __html: html }} />
</div>
);
}
// Render it
ReactDOM.render(
<Example />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
I don't suggest you dangerouslySetInnerHTML. It introduces both security and performance issues, and even if you are working on learning project, you better avoid such an approach.
The reason why your code does not work, JSX does not magically convert string "<br>" into appropriate element (until there is dangerouslySetInnerHTML, sure).
But JSX can render arrays just fine. It allows us to split initial string into elements: string.split(', ') and then inject JSX's <br /> with the help of .flatMap()(think about it as if .join() could return array with additional elements in between elements of source array).
{
string.
split(', ').
flatMap((el, index) => index ? [<br />, el]: el)
}
This approach is way more powerful than dangerouslySetInnerHTML since instead of simple BR you may use any JSX tree with React custom components, context and event handlers.
Another approach is to replace ', ' with newlines and apply CSS style white-space: pre-wrap(check white-space docs on all values available)
I want to make id like this dynamically.
<div id="track_1"></div>
<div id="track_2"></div>
So I gave the id like this from parent component.
export default function Components(props) {
return (
<AudioTrack trackNum="1"/>
<AudioTrack trackNum="2"/>
)
}
then in my AudioTrack Component I got the trackNum and want to use like this
const AudioTrack = (props) => {
return(
<div id="track_{props.trackNum}" ></div>
);
}
Howeber it doesn't work.
Is there any good way?
Since the div prop isn't a constant string, you need {} to indicate an expression, and then either use + to concatenate or a template literal with ${}:
<div id={`track_${props.trackNum}`}></div>
Is it possible to put JSX inside a template string that is being used as a React render prop?
This is what I'm trying to do, but it leads to the link rendering as [object Object]
const Container = ({ message }) => <div className="from line 4"> {message}</div>;
const Link = () => juan;
const App = () => (
<div>
<Container message={`My message with a ${<Link />}`} />
</div>
);
One thing I tried was to put JSX instead of a template string inside message. This works, but it introduces a new div that isn't needed.
<Container
message={<div>My message {<Link />}</div>}
/>
I made this codesandbox to illustrate the problem
You can use a Fragment to render inline like you are trying to do and to prevent adding a new wrapping <div />:
const App = () => (
<div>
<Container
message={<React.Fragment>My message with a <Link /></React.Fragment>}
/>
</div>
);
Here is a forked version of your Codesandbox using React.Fragment: https://codesandbox.io/s/nrmr9l34vl