-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Propose: Better support React simple use cases #2537
Comments
First response from the original mixed thread: For React.js I use the following simple wrapper. import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import hljs from 'highlight.js/lib/core';
import excel from 'highlight.js/lib/languages/excel';
hljs.registerLanguage('excel ', excel);
const SyntaxHighlighter = ({ sourceCode }) => {
const [parsedCode, setCode] = useState(null);
useEffect(() => {
function highlight() {
let highlighted = hljs.highlight('excel', sourceCode);
setCode(highlighted.value);
}
highlight(sourceCode);
}, [sourceCode]);
return (
<div>
<pre
contentEditable={false}
className="excel"
dangerouslySetInnerHTML={{ __html: parsedCode }}
/>
</div>
);
};
SyntaxHighlighter.propTypes = {
sourceCode: PropTypes.string,
};
SyntaxHighlighter.defaultProps = {};
export default React.memo(SyntaxHighlighter); Originally posted by @andrewQwer in #2535 (comment) |
I would not recommend |
|
I agree it's not ideal if you have to use them but |
So using code via refs that itself calls |
This seems to be arguing in favor of |
In Vue we can just make the highlighted code a computed property and then insert it into the template via variable... passing the code into the component as a prop... surely this type of thing is also possible in React? The sample above looks a lot like I'd expect that might look but I dunno about all the effect stuff and if there is a simpler way to write it - or if React just requires more boilerplate than Vue. Highlight.js generates raw HTML... that by it's nature is a [potentially] dangerous thing... |
IE, I think the "simplest" form in Vue might look something like: export const Component = {
props: ["language", "code"],
computed: {
className( ... ) {},
highlightedCode() {
this.highlightedCode = hljs.highlight(...)
}
},
template: `<pre><code :class="className" v-html="highlightedCode"></code></pre>`
}; What would the equivalent be in React? |
I guess it is fine if hljs already escapes dangerous characters in the source. Minimal example could be function Component({language, code}) {
const [highlightedCode, setHighlightedCode] = useState(code);
useEffect(() => {
setHighlightedCode(hljs.highlight(language, code));
}, [code]);
return (
<pre>
<code dangerouslySetInnerHTML={{__html: highlightedCode}}/>
</pre>
);
}; This will initially render unhighlighted and do another render once highlighting is done. I guess one could block the first render until highlighting is done, but it'll be more complicated. |
And could you share what that would look like as pure JS without the JSX? |
We currently do
Should that cover it? I'm not sure (off the top of my head) how the quotes or / could break out on their own though without the tag characters... I think the quotes are more about raw insertion anywhere (like in the middle of an HTML attribute) as shown here: That's not what we do... although now I'm wondering if there is a potential attack vector with a evilly coded grammar via className. Although grammars already run any JS they want freely though, so some sort of attack via className would be the HARD way to do it. |
Here's a JSX-less working example: https://codesandbox.io/s/intelligent-dubinsky-zkkrj |
Pulling in code from external site inline:
@silverwind Is there no way to do this without pulling in a ton of React requires? We are not a React project and do NOT want to add React to our dependencies... We just need a tiny little "stand-alone" snippet that someone can "register" with React. The build product would be a "stand-alone" JS file that someone just adds to their site. This was trivial with Vue.js. Does React have nothing similar? The goal:
Does this not exist in the React world? |
You can omit the Also, one would generally write this in JSX which requires a Babel transform to transpile it to Just show a dependency installation and JSX example and assume the user has installed a toolchain to build React like create-react-app. |
Yeah it's starting to sound like perhaps this belongs in documentation somewhere rather than the library... Just having static documentation (ie, a static JS "example") is likely to age poorly over time and not be well maintained. This issue made much more sense when I thought we could perhaps just add a little React "glue" to our library to making using us with React easier for someone "getting started" (ie, like our simple drop-in Vue support). Seems it's much more involved than that. At this point I think pointing to a well-written/maintained React component that someone in the React community has already written (and could support and answer questions about, etc) is the best route to go. If you know a good one we could mention that'd be great. Closing this issue. |
In the case of react, is there more to this? I have the exact code as in the above examples, and it works great locally, but when I do "yarn build" it stops with the following error:
Well, except i'm using html-react-parser instead of dangerouslySetInnerHTML |
What version is this. If you look at |
Creating this thread to discuss if we might provide a simple/small React plugin/component to make using Highlight.js as part of a React application a little easier to get started.
The text was updated successfully, but these errors were encountered: