Mendes
Mendes

Reputation: 18451

ReactJS get ref to child element and setting its scrollTop position

Consider the following rendered ReactJS component:

render () {
   return (
            <div className='ux-table' onScroll={this.handleScroll}>
              <table ref='mainTable>
                 <Header>
                 **Rows data here***
              </table>
            </div>
          );

And the Header child component:

render () {
    return ( 
             <thead ref='tableHeader'>
                 <tr> ** column data here **  </tr>
             </thead>
           );
} 

I need to, on the main component handle, get the scrollTop position of the main component (mainTable) and set it to the child Header component (tableHeader), as the following Javascript code:

document.querySelector('.ux-table').onscroll = function (e) {
  // called when the window is scrolled.
  var topOfDiv = Math.max(document.querySelector(".ux-table").scrollTop - 2, 0);
  document.getElementsByTagName('thead')[0].style = "top:" + topOfDiv + "px;";
}

My try on main component:

handleScroll = (event) => {
      var topOfDiv = Math.max(this.refs.mainTable.scrollTop - 2, 0);
      this.refs.tableHeader.scrollTop = topOfDiv;
  }

In first line I´m getting zero (0) for this.refs.mainTable.scrollTop. On second line, I´m getting an error as I cannot access the subcomponent directly.

In short, how to:

a) Read and set the scrollTop attribute of a React component using ref

b) Get access to a child component from its parent ref

Thanks for helping.

Upvotes: 3

Views: 2195

Answers (1)

Philippe T.
Philippe T.

Reputation: 1192

I'm not sure that's help , but i made a component based on react-markdown.

It show help page wrote in markdown and scroll to the header depending on the context.

After rendering component , i search for the header based on markdown header :

import React, { Component } from 'react';
import Markdown from 'react-markdown';

export default class Help extends Component {
    constructor(props) {
        super(props);
        this.state = {
            md : null
        }
        this.helpref = React.createRef();
        this.fetchdata()
    }

    fetchdata() {
        fetch("Help-Page.md")
         .then((r) => r.text())
        .then(text  => {
            this.setState({
            md:text
        });

        })

    }
   
    componentDidUpdate(){
        // Here i search for the header like : ## My Header
        let part=this.props.helpHeader.match(/(#+)\s(.*)/)
        // If I found it , i search on child for it
        if(part)
        for(let childnod of this.helpref.current.childNodes)
        {
            // If the child is found
            if(childnod.nodeName == "H"+part[1].length && childnod.innerText== part[2])
            {
                // I scroll to the element
                this.helpref.current.scrollTop = childnod.offsetTop
            }
            
        }

    }
    render() {
        
        return (
                      <div className="help" ref={this.helpref}>
                            <Markdown source={this.state.md} />                            
                        </div>

        );
    }
}

take care of the

this.helpref = React.createRef();

it's needed to get element after rendering and it not work on React Component

Upvotes: 1

Related Questions