How to prettify dynamic code snippets in React? - reactjs

I've looked into code prettifiers like google-code-prettify, beautify, etc. Unfortunately, I haven't been able to get any of these to work in my React app. I am currently using react-ace to display dynamically populated code snippets, but they are only color-highlighted, not formatted.
Are there any simple examples of some way that I can get this to work in a React App? It doesn't have to be using Ace editor - that was sort of my hack to get the code displayed somewhat nicely.

Thanks for this question, you can use prettier to format the code. You may need to configure different parser based on the language or framework you are using.
Here is a sample codesandbox for formatting JS code. Link: https://codesandbox.io/s/currying-architecture-tm785?file=/src/App.js
Code for the main file:
import React from "react";
import prettier from "prettier/standalone";
import babylon from "prettier/parser-babel";
import "./styles.css";
export default function App() {
const [code, setCode] = React.useState(`
const a = "abc";
const b = 'a'
console.log(a);
`);
const formatCode = () => {
const formattedCode = prettier.format(code, {
parser: "babel",
plugins: [babylon]
});
setCode(formattedCode);
};
return (
<div className="App">
<textarea
style={{ height: "100px", width: "100%", display: "block" }}
value={code}
/>
<button onClick={formatCode}>Format Code with Prettier</button>
</div>
);
}
Hope this helps!

Related

Importing/exporting styled components in React causes invalid hook calls

I am working on a React project (react#18.2.0, styled-components#5.1.1) that has been set up to use styled-components so that commonly used components are exported from a common/styled.js file, but that causes a great amount of invalid hook call errors.
Right now, it looks something like this:
export const ExampleButton = styled.button`
color: white;
`;
And then those styled componets are imported where needed, like this:
import { ExampleButton, SomeComponent, AnotherComponent } from '../common.styled';
I know they invalid hook calls are caused by this export/import setup, because the error message for one particular styled component goes away when I remove it from common/styled.js and instead paste it locally everywhere it's needed, so that instead of this:
import { ExampleButton } from '../common.styled';
const ExampleComponent = () => {
return (
<div>
<ExampleButton>Hello</ExampleButton>
</div>
);
};
I do this:
import styled from 'styled-components';
const ExampleComponent = () => {
const ExampleButton = styled.button`
color: white;
`;
return (
<div>
<ExampleButton>Hello</ExampleButton>
</div>
);
};
So that works, but it's not really a viable solution, because I would have to paste the same code everywhere, not just ExampleComponent, and doing that for the whole project would result in a massive amount of code repetition.
What is the right way to create a solution similar to common/styled.js here in a way that doesn't break the Rules of Hooks?
It seems that there had been an issue between some older versions of styled-components and React 18 that have been solved in v5.3.1.
https://github.com/styled-components/styled-components/pull/3564
Maybe upgrading styled-components to v5.3.1 or higher would solve the issue.

ReactJS highlight blog post that comes from the server

I've been trying to use highlight.js with my react project , but it never worked.
I have a blog, and for each post I fetch the post data from the server.
Unfortunately - highlight.js does not work properly when it comes to dynamic data and async proccess.
Lets say we have this code that i fetch:
bla blba blahbla blba blahbla blba blahbla blba blah...
<code><div class="test"></div></code>
bbla blba blah....
So , I did try to import highlight.js with the css theme, and used hljs.highlightAll() , but it didn't work properly.
Maybe there is some other solution \ library where I can highlight the code?
What's the alternative?
thank you.
import { React, useEffect } from "react";
import { useParams } from "react-router-dom";
import hljs from "../../node_modules/highlight.js/lib/core";
import "../../node_modules/highlight.js/styles/arta.css";
import "./BlogPost.css";
function BlogPost(props) {
hljs.initHighlightingOnLoad();
const updateCodeSyntaxHighlighting = () => {
document.querySelectorAll("code").forEach((block) => {
hljs.highlightBlock(block);
});
};
useEffect(() => {
getPostData();
updateCodeSyntaxHighlighting();
}, []);
// GetPostDataById(id);
return <div dangerouslySetInnerHTML={{ __html: postData }}></div>;
}
export default BlogPost;
result:
as you can see - the background gets darker , but not really highlighted text.
Your not importing the entire highlight.js library so you can just do import hljs from 'highlight.js' instead of going into the node modules folder to get it. Also you are not specifying the language you want to highlight in with the class of the code block. In the example I am just going to hard code the postData with class='language-javascript' for the <code> block to get the correct syntax highlighting. So here is a working example:
Working Codesandbox
import { React, useEffect } from 'react'
import hljs from 'highlight.js'
import '../../node_modules/highlight.js/styles/arta.css'
const postData = `<pre><code class="language-javascript">console.log('hello');</code></pre>`
function BlogPost(props) {
const updateCodeSyntaxHighlighting = () => {
document.querySelectorAll('code').forEach((block) => {
hljs.highlightElement(block)
})
}
useEffect(() => {
updateCodeSyntaxHighlighting()
}, [])
// GetPostDataById(id);
return <div dangerouslySetInnerHTML={{ __html: postData }}></div>
}

Using hover-effect in Next JS

I'm trying to use an npm package called hover-effect inside a functional component, but I'm constantly bumping into some issues. I have used similar packages in create-react-app before but I'm new to next.js. See below how the package should be used:
import React, { useEffect, useRef } from "react";
import HoverEffect from "hover-effect";
export default Card(){
const container = useRef();
useEffect(() => {
console.log(container.current);
new HoverEffect({
parent: container.current,
intensity: 0.3,
image1: "https://picsum.photos/420/620",
image2: "https://picsum.photos/420/620",
displacementImage:
"https://raw.githubusercontent.com/robin-dela/hover-effect/master/images/fluid.jpg",
});
}, [container]);
return(
<>
<div
className="outer-image"
ref={container}
id="imgContainer"
style={{ height: 500, width: 400 }}
>
</div>
</>
)
First of all, I tried to import it like any other npm module, but I get the issue
SyntaxError: Cannot use import statement outside a module
I have tried to import the package dynamically using next/dynamic in this way:
const HoverEffect = dynamic(() => import('hover-effect')), {ssr: false});
But when I try to use 'new' syntax I get the error 'HoverEffect' is not a constructor.
I even tried adding next js transpile module as
next.config.js:
const withTM = require("next-transpile-modules")([
"gsap",
"hover-effect",
]);
module.exports = withTM();
Anyone aware of any solution would be a lifesaver
I just tried to import it in my localhost. This solution is working fine
const withTM = require("next-transpile-modules")([
"gsap",
"hover-effect",
]);
module.exports = withTM();
You also need to make sure that your import is like this
import HoverEffect from "hover-effect";

loading pdf using react-pdf

I am trying to display pdf using react-pdf in create-react-app application.
I followed the instructions but the pdf is not displayed.
import { makeStyles, Box, Grid } from "#material-ui/core";
import React, { useState } from "react";
import Header from "./header";
import contractPdf from "../../sample.pdf";
import { Document, Page } from "react-pdf";
const useStyles = makeStyles((theme) => ({
root: {
padding: "32px 24px 14px 24px",
},
pdfArea: {
borderRight: "1px solid #DDDDDD",
height: "calc(100vh - 195px)",
},
}));
const BasicComponent = (props) => {
const classes = useStyles();
const [numPages, setNumPages] = useState(null);
const [pageNumber, setPageNumber] = useState(1);
function onDocumentLoadSuccess({ numPages: nextNumPages }) {
setNumPages(nextNumPages);
}
return (
<Box className={classes.root}>
<Header />
<Grid container>
<Grid item xs={8}>
<Box className={classes.pdfArea}>
<Document
file={contractPdf}
onLoadSuccess={onDocumentLoadSuccess}
options={options}
>
<Page pageNumber={1} />
</Document>
</Box>
</Grid>
<Grid item xs={4}>
<Box className={classes.inputArea}>User input</Box>
</Grid>
</Grid>
</Box>
);
};
export default BasicComponent;
I checked the debug in development mode and it shows Uncaught SyntaxError: Unexpected token '<' in pdf.worker.js
Can anyone help me?
I appreciate your help. Thank you
I wasted so much time that I decided to write an answer to this question to help anybody in my situation avoid the waste of time. The instructions as described in the github site for react-pdf do not work with react 17.02 CRA 5 and Webpack 5.6.6 regarding the pdf.worker.js worker.
As the site indicates without giving a clear solution,
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack5';
creates a heap out of memory error during compilation that is not fixed even by allocating 8 gigabytes of memory.
Using the standard instructions doesn't work either, creating an error that is dependent of the last web directory that was used in your react-router routes. This creates a weird bug, because sometimes it works and sometimes it doesn't.
The standard instructions say:
that you should add:
import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js';
when using the .min file, instead of the regular .js file, that gave me the idea of adding the following:
import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.js';
But it didn't work either. To make it work I had to do the following:
copy pdf.worker.js and pdf.worker.js.map from pdfjs-dist/legacy/build to public directory (it also works if you copy from the build - not legacy directory)
and,
add to my code the following:
import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.js';
Yes, the '/' did it. Otherwise it'd go back to load my index.html from my /public directory.
As per documentation you have to add this line in your code.(react-pdf)
import { pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`;

React app using Material UI hooks not showing styling in production

I have a react app using Material UI (v4). In my development environment it all works fine.
In production the styling does not seem to be applied.
I have read about class name generation being different in dev to prod and potential clashes but I can't figure out how to fix it.
I have a js file which looks like:
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
someClass: {
backgroundColor: 'red',
},
});
export default useStyles;
I then have multiple tsx files which use this, something like:
const Example = (props: IExampleState) => {
const styles = useStyles();
return (
<SomeMUIElement className={styles.someClass}>
{some inner stuff}
</SomeMUIElement>
)
}
const mapStateToProps = (state: IExampleState) => {
...
}
export default connect(mapStateToProps)(Calls);
In production none of these styling appear, and in dev tools I can see that there are no class names applied either, also appear to be no errors.
I'm sure I am missing something!

Resources