Dynamically loading Material-UI Icons in React - reactjs

I'm trying to make React component that dynamically imports requested Material-UI icon,
when the page loads. My solution presented here works, but it gives warning
at compile time. Additionally it slows down the compilation of the project.
Any idea on how to do this properly?
https://github.com/jurepetrovic/ordermanager_demo
The main logic is found in App.js, lines 5-10:
import React, { Component } from 'react';
import BarChartIcon from '#material-ui/icons/BarChart';
const MaterialIcon = ({ icon }) => {
console.log("icon: " + icon);
let resolved = require(`#material-ui/icons/${icon}`).default;
return React.createElement(resolved);
}
class App extends Component {
render() {
return (
<div>
<MaterialIcon icon={"PowerSettingsNew"} />
</div>
);
}
}
export default App;
The warning it gives is this:
Compile warning

I finally found the simplest solution to this problem:
import all material icons from the package:
import * as Icons from '#material-ui/icons'
I assume you fetch your icon names from your api and finally you have something like this:
var iconNamesArray = ["FitnessCenter","LocalDrink","Straighten"]
Finally load your Icons like below:
<div className="my-icons-wrapper-css">
{
iconNamesArray.map((el,ind)=>{
let DynamicIcon = Icons[el]
return(
<DynamicIcon className="my-icon-css"/>
);
})
}
</div>
And your icons will appear in the screen.

Related

Header layout bug in NextJS

Im trying to make a header in NextJS but this keeps happenning:
I tried to use 100% width, 100% height.
My code:
import type { NextPage } from 'next';
import { Fragment } from 'react';
import Header from '../../components/Header';
const Home: NextPage = () => {
return (
<Fragment>
<Header />
<div>Home</div>
</Fragment>
);
};
export default Home;
The header component(its a div with background color black):
import { Container } from './styled';
const Header = () => {
return <Container>HEADER</Container>;
};
export default Header;
From your code looks like there are 2 possible ways that this can go wrong.
Scenario #01:
Check if there's some global style rules with matching styles i.e background:black in your globals.css (located in styles folder)
Scenario #02
You have the following container being imported in your component.
import { Container } from './styled';
Try commenting this out and then wrap the content in a fragment i.e
<Fragment> HEADER </Fragment>
If this solves the issue of black-background then it means there's something wrong about the container component imported.
Based on the screenshot of the devtools it looks like there's a 8px margin on the background for some reason.
Look in your CSS files if you have any rules that do that.
If this isn't from you, override it by adding a rule in your css like
body {
margin: 0;
}

install quilljs-markdown on react

I need such an editor on react https://cloverhearts.github.io/quilljs-markdown/ , as you can see in it you can put markdown characters directly into the text.
when I do this
import React, { Component } from 'react'
import './App.css'
import ReactQuill from 'react-quill'
import Quill from 'quill'
import QuillMarkdown from 'quilljs-markdown'
const App = () => {
const editor = new Quill('#editor', {
theme: 'snow'
})
new QuillMarkdown(editor)
return (
<div className='app'>
{/*<MyComponent/>*/}
<div id="editor"></div>
</div>
)
}
export default App
I get error TypeError: Cannot read property 'on' of undefined
as I understand I need jQuery for work, but I use react, I found https://www.npmjs.com/package/react-quill this quilljs for react, but I don't know how to combine it with markdown https://www.npmjs.com/package/quilljs-markdown
can anyone help?
I found the solution for this after hours of trying this out.
What you have to do is this:
Create a module for ReactQuill
Register the module.
Pass modules to react quill
Shown Below.
Step 01
const modules = {
markdownOptions: {}
};
Step 02
Quill.register('modules/markdownOptions', QuillMarkdown);
Step 03
<ReactQuill
modules={modules}
/>
It seems like you are trying to initialize the Quill instance and the markdown module before the editor is ready.
Use useEffect hook to initialize it after the div has been rendered:
import {useEffect} from 'react';
...
useEffect(() => {
const editor = new Quill('#editor', {
theme: 'snow'
});
new QuillMarkdown(editor);
});

How to load only needed CSS per component (React js)

I've started to code my first React app and it's awesome, but I can't figure out how to manage css files per-component(so the actual CSS won't load if it is not necessary).
React with webpack(correct me if I'm wrong please) wraps the project in such a way that at every given moment the app loads only what it needs(in terms of JS).
So if I have my main App component with only two buttons visible: btn-01 and btn-02, and inside of this component I have another two: component-01 and component-02, and they are hidden till the corresponded button is clicked(btn-01 for component-01), these components won't be loaded until the actual button is clicked(am I getting this right?), however this is not the same with css as I can tell, because I see the css of each of these(component-01 and component-02) components loaded right away the App is loaded, even though none of the buttons are clicked.
I'm not a big fan of inline styling, but I did test it with css module, but the result is the same in this aspect. So I'm not even sure if this is possible to implement in an easy way.
Here's a code, so perhaps I'm not implementing it correctly, but please don't mind the none-DRY code etc.
So as you may see, the style of Component-01 and -02 are loaded even though there is no need for them at the moment(none of the button is pressed).
App.js
import React, { Component } from "react";
import "./App.css";
import Component_01 from "./Component-01/Component-01";
import Component_02 from "./Component-02/Component-02";
class App extends Component {
state = {
isComponent_01: false,
isComponent_02: false,
};
toggleComponent01 = () => {
this.setState({
isComponent_01: !this.state.isComponent_01,
});
};
toggleComponent02 = () => {
this.setState({
isComponent_02: !this.state.isComponent_02,
});
};
render() {
let showComponent_01 = null;
if (this.state.isComponent_01) {
showComponent_01 = <Component_01 />;
}
let showComponent_02 = null;
if (this.state.isComponent_02) {
showComponent_02 = <Component_02 />;
}
return (
<div className="App">
<button className="btn-01" onClick={this.toggleComponent01}>
Btn-01
</button>
<button className="btn-02" onClick={this.toggleComponent02}>
Btn-02
</button>
{showComponent_01}
{showComponent_02}
</div>
);
}
}
export default App;
Component-01.js (and Component-02.js, just with -02.js)
import React from "react";
import style from "./Component-01.module.css";
function App() {
return <div className={style["component-01"]}>Component-01</div>;
}
export default App;

Unable to render automatic slideshow with react

I'm trying to create an automatic slideshow in react, using react-slideshow. I'm very new to react and have just begun. I got this code from here.
import React from 'react';
import { Fade } from 'react-slideshow-image';
const images = [
'./img/p1.png',
'./img/p1.png',
'./img/p1.png'
];
const Slideshow = () => {
return (
<Fade
images={images}
duration="5000"
transitionDuration="1000"/>
)
}
What I am not getting is how to make this slideshow actually render. What I have done is called this function from inside a component in the same file i.e.
class App extends Component {
render() {
return (
<div className="App">
{Slideshow();}
</div>
);
}
}
export default App;
This is not rendering any slideshow or image, about which I'm not too surprised. The function is running. I console logged something and it got logged on the console. The rest of the page (I have other divs not shown here) is rendered and there is no error thrown. How to make this work?
Nothing seems wrong in this code.
try defining Slideshow() function inside app component.
make a call like "{ this.Slideshow }".
Check by removing "./" in image path. (Try..)
Also check the path of image. Sometime they refer to public folder outside the src folder. maybe public/images/img.png
Slideshow is a React component, so you need to render it using JSX, not invoke the function:
class App extends Component {
render() {
return (
<div className="App">
<Slideshow/>
</div>
);
}
}
export default App;

Using marked in react

I want to use marked in reactjs as described in the reactjs docs.
<div>{marked(mystring)}</div>
I use babel so I import marked like this:
import { marked } from 'marked';
Unfortunately the import statement does not work. marked is not defined.
How do I have to import marked here, so that I can use it?
Here's one way to use marked with React:
Ensure that you've installed marked
Include marked in your project's package.json file:
// package.json
{
dependencies: {
react: "^17.0.0",
marked: "^4.0.0",
},
}
Import marked in your .jsx (or related) file:
import { marked } from "marked";
Use the dangerouslySetInnerHTML approach as shown in the example below:
import React from "react";
import { marked } from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked.parse("This is _Markdown_.");
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />;
}
}
The dangerouslySetInnerHTML attribute gives you the ability to work with raw (HTML) markup. Make sure to take care when using this attribute, though!
Alternative (Safe)
If you don't want to use dangerouslySetInnerHTML and safely render HTML. Try marked-react, which internally uses marked to render the html elements as react components
npm i marked-react
import Markdown from "marked-react";
const MarkdownComponent = () => {
return <Markdown>{rawmarkdown}</Markdown>;
};
Another alternative is react-markdown
Here is another way of using marked with React Hooks:
Create your MarkedConverter component
import { useState } from 'react'
import marked from 'marked'
export const MarkedConverter = () => {
const [markedVal, setMarkedVal] = useState(
'# Welcome to my React Markdown Previewer!'
)
return <div dangerouslySetInnerHTML={createMarkUp(markedVal)}></div>
}
Create Markup function and pass the value from MarkedConverter Component
export const createMarkUp = (val) => {
return { __html: marked(val) }
}
Finally you can import MarkedConverter Component to any of your Component
With the marked-wrapper react-marked-markdown:
import { MarkdownPreview } from 'react-marked-markdown'
export default ({ post }) => (
<div>
<h1>{ post.title }</h1>
<MarkdownPreview value={ post.content }/>
</div>
)
If you just want to import marked:
import marked from 'marked';
Then call the function in your component:
marked('# Markdown');
Here's an example on how to use marked with react:
Install marked with NPM : npm i marked
import it in your react app (this example is created with create-react-app), and using it
example of a react component using "marked"
result in the browser :
preview

Resources