I am trying to sync scroll of two different components in React so that if I scroll one in one component the other component will also scroll. The two are in different ratios so I have to calculate to offsets every time.
I don't want to use state and actions (I am using redux) since it hurts my performance due to re-rendering every mouse scroll (I also tried debouncing/throttling).
I have a wrapper component which renders two other components like so:
class Wrapper extends React.Component {
render() {
return (
<div>
<FirstComponent />
<SecondComponent />
</div>
);
}
}
I tried to use ref
but it doesn't work on custom components (I get undefined
) and in any case this all looks like an anti-pattern for react/redux.
Any suggestion on how to achieve that without hurting performance and staying as close as possible to the React/Redux patterns?
All you need is to: make <ScrollSync> as a common parent to your nodes you want to sync scroll with other nodes (which is a React component that uses React's new Context API) and then wrap each scrollable-node with a <ScrollSyncNode>
Sometimes, you want the state of two components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props.
Some components need to synchronize with external systems. For example, you might want to control a non-React component based on the React state, set up a server connection, or send an analytics log when a component appears on the screen.
We can create as many components as we want in the same file, and we can use those components in the same way as we use HTML tags div, span, p etc.
For similar questions in the future you can look at: react-scroll-sync, which saved my work with very complex table syncing case.
A short example how to use:
<ScrollSync>
<div style={{ display: 'flex', position: 'relative', height: 300 }}>
<ScrollSyncPane>
<div style={{overflow: 'auto'}}>
<section style={{ height: 500 }}>
<h1>Left Pane Content</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aperiam doloribus
dolorum
est eum eveniet exercitationem iste labore minus, neque nobis odit officiis omnis
possimus quasi rerum sed soluta veritatis.</p>
</section>
</div>
</ScrollSyncPane>
<ScrollSyncPane>
<div style={{overflow: 'auto'}}>
<section style={{ height: 1000 }}>
<h1>Middle Pane Content</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aperiam doloribus
dolorum
est eum eveniet exercitationem iste labore minus, neque nobis odit officiis omnis
possimus quasi rerum sed soluta veritatis.</p>
</section>
</div>
</ScrollSyncPane>
</div>
</ScrollSync>
I have created this library recently, that solves your issue
All you need is to:
<ScrollSync>
as a common parent to your nodes you want to sync scroll with other nodes (which is a React component that uses React's new Context API)<ScrollSyncNode>
and then the sync happens :D
check this codesandbox
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With