How do I insert icon in from createElement - javascript

I am currently using Material-UI-icon and need to create the icon by in javascript.
Is there a way where I can do this?
import ThumbUpIcon from '#material-ui/icons/ThumbUp';
var thumbsup = document.createElement(ThumbUpIcon);
Thanks!

Instead of document.createElement I would use as a variable or like <ThumbUpIcon />.
You can try the following:
import ThumbUpIcon from '#material-ui/icons/ThumbUp';
var thumbsup = <ThumbUpIcon />;
Then in the return part:
const YourComponent = () => {
return (
<div>
<h1> First option: </h1>
{thumbsup}
<h1> Second option: </h1>
<ThumbUpIcon />
</div>
)
}
Additionally I would suggest to read: Creating React Elements
I hope that helps!

Related

ReactJS fetched html data manupilation

I have a mongodb database where I saved raw html in it. I have created a custom attribute in the html called kk-id to mention objects inside the html. I want to replace that particular html tag with an anchor tag.
I figured a way to do it using vanilla javascript, however I was wondering if there was a more efficient reactjs way to do it.
data example
<p>Hello <span kk-id="123">John Doe</span></p>
where John Doe's id is 123 saved in it.
/// react component
import React, { useEffect, useState } from "react";
export default function TestComponent() {
const [html, setHtml] = useState(
`<p>Hello <span kk-id="123">John Doe</span><br /></p>`
);
useEffect(() => {
const span = document.querySelector(`[kk-id]`);
if (span) {
const a = document.createElement("a");
a.href = "/people/john-doe";
a.innerText = span.innerText;
span.parentNode.replaceChild(a, span);
}
}, [html]);
return <div dangerouslySetInnerHTML={{ __html: html }} />;
}
You can use html-react-parser and just do
import parse from "html-react-parser";
...
const newParsedHtml = parse(html, {
replace: ({attribs}) => {
if (domNode.attribs && domNode.attribs.id === "123") {
return <span>dynamic text here</span>
}
}
});
I hope vanilla js is the simplest way to do it. For enhancement purpose you can see this. it will be more readable and reusable.

Alternative to document in next.js

I'm still new to learning next.js, but the problem is, I don't understand. How do we call an element from the written html because I want to do like the code written below?
HTML
<div class="container_title">
<div class="main_title">
<h1> Title <span>( Global )</span></h1>
<div class="button_main_title">
<button class="Tap_1 button" >Tap_1 </button>
<button class="Tap_2 button">Tap_2</button>
<button class="Tap_3 button">Tap_3</button>
<button class="Tap_4 button">Tap_4</button>
<button class="Tap_5 button">Tap_5</button>
</div>
</div>
</div>
javascript
const main_title = document.querySelector(".main_title");
const button_main_title = document.querySelectorAll(".main_title button");
(() => {
main_title.addEventListener('click', event => {
if(event.target.classList.contains("button")){
for(i=0;i<button_main_title.length;i++) button_main_title[i].classList.remove("active");
event.target.classList.add("active")
}
})
})();
const Firsr_BTN = document.querySelector(".button_main_title .button:first-child");
Firsr_BTN.click();
NextJS is a framework which is based on React, which is based on Javascript. However, the only way that I know to select an element is to use a React hook called useRef. Let me give you an example.
import React, { useRef } from 'react'
const YourComponent = () => {
const myHeading = useRef()
console.log('heading', myHeading)
return (
<div>
<h1 ref={myHeading}>Heading</h1>
</div>
)
}
Now you have your h1 as myHeading and you can modify it the way you want. Always check your console for what's the element object looks like and how to edit it.

Reactjs - how can i make line break in template strings and return for rendering?

You need to display the following content formatted on the screen:
divs:
<div>my text</div> <div>my text</div>
i tried to do this, but everything came out without line break:
const HtmlCreator=()=>{
let text="my text";
return (`divs: \n <div>${text}</div> <div>${text}</div> `)
{
return (
<div>
<p><HtmlCreator/></p>
</div>
)
Add whiteSpace:'pre' to your style :
<p style={{whiteSpace:'pre'}}><HtmlCreator /></p>
this is useful when you cannot modify the original data.
You can use <br />, but you'll need a wrapper. For that, you can use <React.Fragment>:
import React, { Fragment } from "react";
const HtmlCreator = () => {
let text = "my text";
return (
<Fragment>
divs
<br />
{`<div>${text}</div> <div>${text}</div>`}
</Fragment>
);
};
CodeSandbox Example
Your question implies you'd like to show the HTML itself (escape it) and not render it. If you meant the latter, you could do:
const HtmlCreator = () => {
let text = "my text";
return (
<Fragment>
divs
<br />
<div>{text}</div>
<div>{text}</div>
</Fragment>
);
};
CodeSandbox Example

Why props alone are being used in called React function component?

I was learning React and I came to a point which created confusion. Everywhere I was using props while writing Function components.
I always use props.profile and it works fine. But in one code component, I had to write
const profiles=props; and it worked fine.
I tried using const profiles=props.profile; and also I tried using inside return in 'Card' function component
{props.profile.avatar_url} but both of them failed
Below is my code which works fine
const Card=(props)=>{
const profiles=props; //This I dont understand
return(
<div>
<div>
<img src={profiles.avatar_url} width="75px" alt="profile pic"/>
</div>
<div>
<div>{profiles.name}</div>
<div>{profiles.company}</div>
</div>
</div>
);
}
const CardList=(props)=>{
return(
<div>
{testDataArr.map(profile=><Card {...profile}/>)}
</div>
);
}
Can someone please help me understand why I can't use const profiles=props.profile?
What are the other ways to achieve the correct result?
Your testDataArr might be this,
testDataArr = [{avatar_url:"",name:"",company:""},{avatar_url:"",name:"",company:""},{avatar_url:"",name:"",company:""}]
Now when you do this,
{testDataArr.map(profile=><Card {...profile}/>)}
here profile = {avatar_url:"",name:"",company:""},
and when you do,
<Card {...profile}/>
is equivalent to,
<Card avatar_url="" name="" company=""/>
In child component, when you do this,
const profiles=props;
here props = {avatar_url:"",name:"",company:""}
So you can access it's values,
props.avatar_url
props.name
props.company
But when you do this,
const profiles=props.profile
profile key is not present in {avatar_url:"",name:"",company:""} object and it fails.
OK. Here is the issue, the props object does not contain a profile attribute, but IT IS the profile attribute. Becouse you are spreading the profile variable when you render the Card element (in the CardList), you basically are writing:
<Card avatarUrl={profile.avatarUrl} comapny={profile.comany} />
Instead, you should do
<Card profile={profile} />
and then in your Card component access the data this way
const Card = (props) => {
const profile = props.profile
}
or even simpler
const Card = ({profile}) => {
return <div>{profile.comany}</div>
}

How to add a <br> tag in reactjs between two strings?

I am using react. I want to add a line break <br> between strings
'No results' and 'Please try another search term.'.
I have tried 'No results.<br>Please try another search term.'
but it does not work, I need to add the <br> in the html.
Any ideas how to solve it?
render() {
let data = this.props.data;
let isLoading = this.props.isLoading;
let isDataEmpty = Object.entries(data).length === 0;
let movieList = isLoading ? <Loader /> : isDataEmpty ? 'No results. Please try another search term.' :
Object.entries(data).map((movie, index) => <MovieTile key={index} {...movie[1]} />);
return (
<div className='movieList'>{movieList}</div>
);
}
You should use JSX instead of string:
<div>No results.<br />Please try another search term.</div>
Because each jsx should have 1 wrapper I added a <div> wrapper for the string.
Here it is in your code:
render() {
let data = this.props.data;
let isLoading = this.props.isLoading;
let isDataEmpty = Object.entries(data).length === 0;
let movieList = isLoading ? <Loader /> : isDataEmpty ? <div>No results.<br />Please try another search term.</div> :
Object.entries(data).map((movie, index) => <MovieTile key={index} {...movie[1]} />);
return (
<div className='movieList'>{movieList}</div>
);
}
You can use CSS white-space to solve the problem.
React Component
render() {
message = `No results. \n Please try another search term.`;
return (
<div className='new-line'>{message}</div>
);
}
CSS
.new-line {
white-space: pre-line;
}
OUTPUT
No results.
Please try another search term.
break text to line:
render() {
...
<div>
{this.props.data.split('\n').map( (it, i) => <div key={'x'+i}>{it}</div> )}
</div>
...
Some HTML elements such as <img> and <input> use only one tag. Such tags that belong to a single-tag element aren't an opening tag nor a closing tag. Those are self-closing tags.
In JSX, one has to include the slash. So, remove <br> and try <br />
Here is how I got around this. Let message be the prop/variable that has the string containing line breaks to be displayed in HTML as follows:
message = 'No results.<br>Please try another search term.';
<div>
{message}
</div>
To make this work, we need to use \n instead of break tag <br> and set the following css on the wrapper element of this message as follows:
message = 'No results.\nPlease try another search term.';
<div className="msg-wrapper">
{message}
</div>
CSS:
.msg-wrapper {
white-space: pre-wrap;
}
OUTPUT:
No results.
Please try another search term.
If you don't want put the string inside a <div> you could use <> to do it.
Like this:
var text = <>This is a text in the first line;<br />this is a text in a second line</>;
Just split text by /n, I do this in this way:
<div>
{text.split('\n').map((item, i) => <p key={i}>{item}</p>)}
</div>
Try with span
return (
<div className='movieList'><span>{movieList}</span></div>
);
If you are like in my situation and you don't want to add css, you can do that :
render () {
...
return (
...
<Typography component="p">
...
{(contact.lastname)?<div>Hello {contact.firstname} {contact.lastname}</div>:''}
...
</Typography>
...
);
}
using ` worked for me however i am not sure if it is the exact solution to the problem :
import React from 'react';
import ReactDOM from 'react-dom';
let element = (
<div>
<h1> Hello world</h1>
This is just a sentence <br></br>
But This line should not be in the same previous line. <br></br>
The above content proves its working. <br></br>
npm v6.14.6 | react : {React.version}
</div>
);
ReactDOM.render(element,document.getElementById("html-element-id"))
You can add a span tag and add block as a class.
Pomodoro Technique Timer <span className="block">with Bla</span>
The simplest thing which I did is by creating a component.
const EmptySpace = ({ spaceCount = 0 }) => {
return (
<>
{Array.from({ length: spaceCount }, (item, index) => {
return <br key={index} />;
})}
</>
);
};
export default EmptySpace;
<EmptySpace spaceCount={1} />
In your case you could do something like this:
const msg = (
<p>
No results <EmptySpace spaceCount={2} />
Please try another search term.
</p>
);

Categories

Resources