Skip to content
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

Added tutorial for using Prism.js with React #1979

Merged
merged 2 commits into from
Jul 20, 2019

Conversation

realfresh
Copy link
Contributor

Hey guys, thought this would be helpful to write. I love Prism but always felt a bit lost trying to use it with React. Hopefully this helps others in a similar position.

@realfresh realfresh changed the title Add tutorial for using Prism.js with React Added tutorial for using Prism.js with React Jul 14, 2019
@RunDevelopment
Copy link
Member

That you for creating the tutorial!

@mAAdhaTTah Could you please review it? I'm not familiar with the Babel plugin.

Changed the domain of my blog where the tutorial was hosted, old URL is 301 forwarded incase
@mAAdhaTTah
Copy link
Member

Reading over the tutorial now. I love having this on the site, but have a few comments for OP:

Keep in mind that the loader won’t add the required styles for some plugins.

This shouldn't be the case if css: true in the plugin. If it is, could you file an issue on the babel plugin repo?

setTimeout(() => Prism.highlightAll(), 0);

I'd actually suggest, for usage with React, using the highlightElement API along with a ref. This would allow you to use both componentDidMount / componentDidUpdate to rehighlight if the code snippet changes (e.g. if it was provided via props). If you wanna get really fancy, doing this with Hooks would be really nice as well.

Also, the use of curly quotes in the code snippets is breaking highlighting, I think, and will def not work for people who want to copy the snippet.

The babel plugin configuration is super helpful though, thank you for including that! I know the docs for the babel plugin are a bit meh, and we've got a few bugs / issues to iron out.

That said, I'd still merge this.

@realfresh
Copy link
Contributor Author

@mAAdhaTTah , thank you very much for your thoughtful suggestions. I will make the necessary changes to the tutorial and post here when it's updated.

@realfresh
Copy link
Contributor Author

realfresh commented Jul 20, 2019

@mAAdhaTTah, I've reviewed the tutorial and made the following changes.

  • Corrected the part about the plugin not importing styles, that was my mistake
  • Add extra component-based example that makes use of highlightElement API with a React ref. This also works when the code or language is updated
  • Fix all the curly quotes, as you were right, they don't copy and paste correctly. My grammar checker messed me up there

Thanks again for taking the time to read and giving feedback. @RunDevelopment, thanks as well for considering the tutorial

@RunDevelopment
Copy link
Member

I'm not a React developer, but using this inside an arrow function will refer to the global this.
Does TypeScript do some magic to make it work or is this a mistake?

  highlight = () => {
    if (this.ref && this.ref.current) {
      Prism.highlightElement(this.ref.current)
    }
  }

@realfresh
Copy link
Contributor Author

realfresh commented Jul 20, 2019

An arrow function as I wrote ensures that the function is bound to the component. Meaning no matter the context in which the function is executed, this will always make reference to the components this. Fortunately, this has nothing to do with typescript specifically.

For example, if I wrote that function normally like

highlight() {
    if (this.ref && this.ref.current) {
      Prism.highlightElement(this.ref.current)
    }
}

Then say I tried to do this

componentDidMount() {

  // this would throw an error
  setTimeout(this.highlight, 0)

  // this would still work
  setTimeout(() => this.highlight(), 0)

  // this would throw an error, pretty sure
  setTimeout(function() {
    this.highlight()
  }, 0)

}

The highlight function would run but there would be no this.ref and an error would occur. The only way around it would be to bind the function to the component manually in the constructor like this

constructor(props) {
  super(props)
  this.highlight = this.highlight.bind(this)
}

As such, using the arrow function syntax avoids needing to do that and is a bit of a shortcut. It just ensures that this will be correct no matter where and how the function is run. Hope that makes sense. Also, how did you know I was using typescript? Hope I didn't leave a trace of it somewhere.

@RunDevelopment
Copy link
Member

Hope that makes sense.

It does! Thanks for the explanation. I just learned something new.

@mAAdhaTTah
Copy link
Member

Looks good! One minor nit:

React.Component<Props> is TypeScript, which is a bit out of place in the JS tutorial.

@mAAdhaTTah mAAdhaTTah merged commit f1e16c7 into PrismJS:master Jul 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants