Jared Nielsen
Jared Nielsen

Reputation: 13

Using Refs in a Dynamic Length Array for scrollIntoView

I am somewhat new to using useEffect and useRef. What I'm trying to do is create a content management system that enables scrollIntoView for n number of page elements from a database for a single page scrolling app.

I'm not able to get it to work so I'm hoping for some assistance.

I've posted a simple test where I have a functional react component where section 2 works (clicking the button scrolls down to the page element.

But my goal is to take 'n' sections from a database and create 'n' number of refs to scroll down to 'n' number of sections.

I tries useRef, useEffect, etc but I'm stumped. My code snippet shows a working example with manual ref declarations for Section 2 but Section 1 attempts to use a collection of Refs and that's not working

Here is a code example: https://codesandbox.io/embed/trusting-stallman-bsjj1?fontsize=14

import React, { useRef } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const App = () => {
  let pageRef = useRef([
    React.createRef(),
    React.createRef()
  ]);


  const pageHomeRef = React.createRef();

  const scrollToRef = ref => ref.current.scrollIntoView({ behavior: "smooth" });
  const scrollToPane = ref => scrollToRef(ref);

  return (
    <div className="App">
      <div className="menu">
        <button
          onClick={() => {
            scrollToPane(pageRef[1]);
          }}
        >
          Scroll to Section 1
        </button>
        <button onClick={() => scrollToPane(pageHomeRef)}>
          Section 2
        </button>
      </div>
      <div className="page" style={{ marginTop: "1500px", marginBottom: "1500px" }}>
        <div className="section1" ref={pageRef[1]}>
          Section 1
        </div>
        <div className="section2" ref={pageHomeRef}>
          Section 2
        </div>
      </div>
    </div>
  );
};

I'd like to feed an array of page elements and have the refs dynamically change as needed.

Upvotes: 1

Views: 3089

Answers (1)

Omer
Omer

Reputation: 3486

Little order the code - try it

You can use React.createRef() or useRef(null) in the array.

And make us many refs you want in array.

And even make map if you have a list (https://dev.to/ajsharp/-an-array-of-react-refs-pnf) And you have other ways insted of refs.

import React, { useRef } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const App = () => {
  let pageRef = [useRef(null),useRef(null)];
  const pageHomeRef = [React.createRef(),React.createRef()];

  const scrollToRef = ref => ref.current.scrollIntoView({ behavior: "smooth" });
  const scrollToPane = num => scrollToRef(pageRef[num]);

  return (
    <div className="App">
      <div className="menu">
        <button
          onClick={() => {scrollToPane(0)}}>Scroll to Section 1</button>
        <button onClick={() => scrollToPane(1)}>Section 2</button>
      </div>
      <div
        className="page"
        style={{ marginTop: "1500px", marginBottom: "1500px" }}
      >
        <div className="section1" ref={pageRef[0]}>
          Section 1
        </div>
        <div className="section2" ref={pageRef[1]}>
          Section 2
        </div>
      </div>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Upvotes: 1

Related Questions