Develop a module that encapsulates the underlying logic (from the current codebase)

I have developed the following code:

import React from 'react'
import { range } from 'lodash'

const DIV_NUMBER = 5

export default class App extends React.Component {
  constructor(props) {
    super(props)
    this.divs = []
  }

  handleScroll = divIdx => () => {
    const divRef = this.divs[divIdx]
    const left = divRef.scrollLeft
    const top = divRef.scrollTop
    this.divs.forEach(div => (div.scrollLeft = left))
    this.divs.forEach(div => (div.scrollTop = top))
  }

  render() {
    return (
      <div style={{ border: '1px solid tomato' }}>
        {range(DIV_NUMBER).map(i => {
          return (
            <div
              key={i}
              ref={divElem => (this.divs[i] = divElem)}
              onScroll={this.handleScroll(i)}
              style={{
                width: 300,
                height: 100,
                margin: '2px',
                overflow: 'auto',
                border: '1px solid black',
              }}
            >
              <div
                style={{
                  width: 500,
                  height: 400,
                }}
              >
                Unique content...
              </div>
            </div>
          )
        })}
      </div>
    )
  }
}

The code works as intended. It generates 5 resizable div elements, where scrolling one scrolls all of them simultaneously. This functionality is achieved using React references.

Now, I am looking to create a component that encapsulates this logic.

What I envision is something like:

<ScrollDivs>
  {range(DIV_NUMBER).map(i => {
    return (
      <div
        key={i}
        style={{
          width: 500,
          height: 400,
        }}
      >
        All the text goes here...
      </div>
    )
  })}
</ScrollDivs>

Therefore, a ScrollDivs magic component that handles the underlying logic. Users of this component won't need to know the specifics, they just wrap the divs they want synchronized scrolling for within this component.

I'm unsure how to proceed with implementing this. Any guidance would be greatly appreciated.

Answer №1

React.Children.map is a useful method for iterating over props.children, while React.cloneElement helps in passing new props to children:

export default class ScrollDivsSync extends React.Component {
  divs = [];

  handleScroll = e => {
    const { scrollTop, scrollLeft } = e.target;
    this.divs.forEach(div => {
      div.scrollLeft = scrollLeft;
      div.scrollTop = scrollTop;
    });
  };

  render() {
    const { children } = this.props;

    let i = 0;
    const enhancedChildren = React.Children.map(children, child =>
      React.cloneElement(child, {
        onScroll: this.handleScroll,
        ref: divElem => (this.divs[i++] = divElem)
      })
    );

    return enhancedChildren;
  }
}

For an example, you can check out a CodeSandbox with the demonstration

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Looking to expand the spacing between header options in React. Any tips on increasing the blank

Hey there! I'm currently working on aligning my figma design with my react web app. Specifically, I am looking to adjust the spacing between the options in the header section. Does anyone have any suggestions on how to achieve this? Thanks in advance! ...

Displaying Errors from Controllers in React Hook Forms

Currently, I am attempting to generate required errors for my input element that is enclosed within a Controller component from react-hook-form version 7. The Input consists of a Material-UI TextField structured like this; <Controller ...

Prevent useSWR from saving any alterations made to the fetched data

It seems like I'm having some trouble understanding how to properly use useSWR with React. Let me explain the issue in a simpler way: I am fetching data using useSWR and then changing the title of this object. The problem arises when navigating back ...

Using Django Sessions for User Authentication in React Applications

Not a coding query, but rather a general one: When using default authentication in Django (session authentication), what does the frontend (in my case it's React) require? For instance, upon logging in on the browser via the front end login button, th ...

Ways to renew a Cognito session within an asynchronous function to ensure the return of valid credentials

After configuring my Redux store, I have a function that runs to setup Apollo: function configureApollo(store) { return new AWSAppSyncClient({ url: AppSync.graphqlEndpoint, region: AppSync.region, auth: { credentials: async () => {/ ...

Determining the ideal scenario for employing server actions versus client components versus server components

I'm currently exploring how to efficiently share data among my components. My focus is on having an auth_token stored in memory that can be accessed throughout the application. Right now, I see two potential approaches: Using a context provider Imple ...

My eCommerce website is currently experiencing some technical difficulties that need to be addressed

I'm in need of assistance with a particular error I encountered. I was following an ecommerce example application and everything seemed to be going smoothly until I clicked on "Shop Now." At that point, I received the following message: Server Error T ...

Optimal method for a React and HTML Select-component to output String values instead of Integer values

Within my React-class (JSX), I've included the following code: var Select = React.createClass({ onChange: function (ev) { console.log(ev.target.value); }, render: function() { var optionsHtml = this.state.options.map(function (el) { ...

Backdrop behind Material-UI Drawer Component

Struggling with implementing the semi-transparent background overlay for the open side menu in a React application using material-ui. Any suggestions on how to achieve this? http://www.material-ui.com/#/components/drawer ...

Creating new Vue components is happening towards the end of the loop

I am currently encountering an issue with my Vue components. I have structured them in a hierarchy where I have a post-index component displaying all posts, containing a post-view component for individual posts, and within that, a post-like component to ha ...

How can you customize the transition of a drawer in your app?

I have a unique setup where I have two drawers, one on the left and one on the bottom. My goal is to create an interactive effect when the left drawer opens - specifically by increasing the marginLeft and reducing the width of the bottom drawer using some ...

Encountering challenges in resolving the dependency tree of Gatsby

Currently, I'm in the process of adding MDX to my Gatsby project along with all necessary dependencies. To achieve this, I executed the command provided in the official Gatsby documentation: npm install gatsby-plugin-mdx @mdx-js/mdx@v1 @mdx-js/react@ ...

Which is better: using multiple makeStyles or just one in Material UI?

Uncertain about the best approach in this situation. Is it acceptable to generate styles using makeStyles for each component individually, or would it be better to create one in the base component and simply pass down class names? ...

"Encountered an error: Expo command not recognized on Mac operating system

As I dive into the world of react native and embark on my initial project, I encounter an issue while installing the expo cli. After what appears to be a successful installation, I receive this message: + <a href="/cdn-cgi/l/email-protection" class="__c ...

What is the method for customizing the hover color in a mantine.ui menu?

I've been attempting to modify the menu color when hovering over it, but unfortunately, it's not working. Could anyone provide guidance on how to change the hover color in mantine.ui menu? ...

Troubleshooting issue with the spread operator and setState in React, Typescript, and Material-ui

I recently developed a custom Snackbar component in React with Material-ui and Typescript. While working on it, I encountered some confusion regarding the usage of spread operators and await functions. (Example available here: https://codesandbox.io/s/gift ...

Place a material-ui React component at the center of a footer section

I'm facing a challenge with centering a material-ui Simple Breadcrumbs component within a footer as opposed to having it aligned to the left. Even though I'm new to this, I thought it would be straightforward but I can't seem to figure it ou ...

Node Express and React Axios have implemented a CORS policy that restricts access to XMLHttpRequest

Currently, my node server is running on localhost port 5500 and react is on localhost port 3000. I am using Axios to send requests to the node backend. Interestingly, when I set axios.defaults.withCredentials = true, I encounter an error. However, if I swi ...

The technique of binding methods in React

When working with React.js, it's recommended to define your method binding in the constructor for better performance. Here's an example: constructor(props){ this.someFunction = this.someFunction.bind(this); } This approach is more efficient t ...

Testing Material UI withStyles Component with Shallow Rendering in Jest

I am currently working on testing a component that is using withStyles() from Material UI and Jest. My goal is to test the child elements, but I am encountering an issue where my wrapper is coming up as undefined. While I have come across similar posts ab ...