Code Monkey home page Code Monkey logo

Comments (7)

KittyGiraudel avatar KittyGiraudel commented on May 20, 2024

Hello Matt!

Thank you for reaching out and for the detailed bug report. I’ve been having a look at what’s going on, and I can confirm it has nothing to do with Gatsby itself. It would happen on any system using client-side rendering. It can easily be reproduced on CodeSandbox as well for instance.

What I found out is that the problem only happens with footnotes using JSX for their description prop. String footnotes are working as they should. The reason why is that JSX trees don’t pass the memoization (from useMemo) as they’re essentially always different. For that reason the footnotes using JSX get re-rendered when the parent component updates.

An actionable fix (until I figure out how to solve it on the lib side) is to store the JSX tree in a ref so it’s stable across renders.

const MyComponent = () => {
  const footnoteDescription = React.useRef(<>My footnote 2</>)

  return (
    <FootnotesProvider>
      <FootnoteRef description={footnoteDescription.current}>testing more footnotes</FootnoteRef>
      <Footnotes />
    </FootnotesProvider>
  )
}

from react-a11y-footnotes.

KittyGiraudel avatar KittyGiraudel commented on May 20, 2024

Okay, nevermind my previous comment, it was a load of shit. Turns out I can’t type and there was a typo in the code. Shame on me. 😅 This has been fixed in 0.4.3 and I think (I hope) things will be smoother for you.

https://github.com/KittyGiraudel/react-a11y-footnotes/releases/tag/0.4.3

Could you update and let me know if that solves your problem? :)

from react-a11y-footnotes.

8bitmatt avatar 8bitmatt commented on May 20, 2024

Thank you! This fixed the duplication problem 🥳🙌

The 2nd issue still exists. Customizing the Wrapper breaks the css :target
In my simple test (with a custom Wrapper).
<Footnotes Wrapper={props => <div {...props} className="footnotes">{props.children}</div>} />

I can see the DOM re-renders every time I click a different footnotes link (I see Chrome dev tools highlighting the changed DOM nodes in the Elements tab). Clicking the same link twice in a row will not re-render and the target styles show.

When the Wrapper is not customized.
<Footnotes />
The DOM doesn't re-render, so target styles always work as expected

from react-a11y-footnotes.

8bitmatt avatar 8bitmatt commented on May 20, 2024

I also found that customizing only the ListItem causes the same problem.
<Footnotes ListItem={props => <li {...props} />} />

from react-a11y-footnotes.

KittyGiraudel avatar KittyGiraudel commented on May 20, 2024

@8bitmatt Could you try memoizing your components please? Like so:

const FootnotesWrapper = React.memo(props => <div {...props} className="footnotes">{props.children}</div>)
const FootnotesListItem = React.memo(props => <li {...props} />)

<Footnotes Wrapper={FootnotesWrapper} ListItem={FootnotesListItem} />

from react-a11y-footnotes.

8bitmatt avatar 8bitmatt commented on May 20, 2024

React.memo does not seem to help. (If the assignment happens inside the main exported component)

const IndexPage = () => {
    const FootnotesWrapper = React.memo(props => <div {...props} className="footnotes">{props.children}</div>)
    const FootnotesListItem = React.memo(props => <li {...props} />)

return (
    ...
)
};

export default IndexPage

If I move the assignment outside of the component it does help... But, I also tried removing React.memo in that situation and it works too. 🤷

// Seems to help
const FootnotesWrapper = React.memo(props => <div {...props} className="footnotes">{props.children}</div>)
const FootnotesListItem = React.memo(props => <li {...props} />)

const IndexPage = () => {
...
};
// But this works too
const FootnotesWrapper = props => <div {...props} className="footnotes">{props.children}</div>
    
const IndexPage = () => {
...
};

Anyway, I can get by with this! Thank you for helping!

from react-a11y-footnotes.

KittyGiraudel avatar KittyGiraudel commented on May 20, 2024

Hello! 👋 Sorry I’m only now coming back to this.

I think what you explained makes sense: if you declare components within the main component, you end up passing different components to the footnotes for every render, which can cause issues. By declaring them outside of the render lifecycle, they‘re always the same. :)

from react-a11y-footnotes.

Related Issues (7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.