fast-reflexes / better-react-mathjax

MIT License
124 stars 16 forks source link

Getting rid of old typesetted content with NextJS issue #64

Closed jtsshieh closed 3 months ago

jtsshieh commented 3 months ago

Hi! Thanks for creating this wonderful library for MathJax with react; it has been extremely helpful for me.

I'm using this library with Next.js and ran a problem (not sure if next.js is related, assume not): I can't seem to get MathJax/react to get rid of old typesetted content properly. Here's a codesandbox link of a reproduction of my issue in a smaller environment: https://codesandbox.io/p/sandbox/festive-grass-mfcw49.

After choosing a new expression by clicking the button (might have to click the button a few times to actually get a new one), the part of the old content stays in the DOM and the new content is just appended to the front. Is there a way this could be fixed?

Thank you very much in advanced.

fast-reflexes commented 3 months ago

Hi there!

Thanks for the kind words! :) 🙏

Your code looks like this:

<MathJax dynamic>
    {expression}
    <button onClick={() => setExp(Math.random() > 0.5 ? list[0] : list[1])}>
        rerender
    </button>
</MathJax>

In case you run into trouble when you wrap stuff like this, you need to change your approach a little bit.

You can study the second bullet under https://github.com/fast-reflexes/better-react-mathjax?tab=readme-ov-file#general-considerations-dont-skip. This in turn references a rather intricate (according to me) bug in React which hasn't been looked into.

I think this would be solved if you refactor the code to this:

<div>
    <MathJax dynamic>{expression}</MathJax>
    <button onClick={() => setExp(Math.random() > 0.5 ? list[0] : list[1])}>
        rerender
    </button>
</div>

I could explain why but you can read about it in the docs and also in the bug ticket I filed in React :)

Let me know if it works!

PS! You can of course use any other element except a div as wrapping element :D

jtsshieh commented 3 months ago

Hi. My code didn't have the button inside, but I was able to resolve it through the "Do's and Don't" section of the docs. My actual code included

<MathJax dynamic inline hideUntilTypeset="first">
    <b>Directions</b>: {directions}
</MathJax>

and I saw that I cannot mix literal and expressions so I wrapped it in span:

<MathJax dynamic inline hideUntilTypeset="first">
    <b>Directions</b>: <span>{directions}</span>
</MathJax>

and it worked!

Thank you very much for your assistance.