'React - Using Ref from Sibling Functional Component

I'm new to React and I have a bit of a problem. I'm using a library called Tabulator and I need to call a Tabulator method from a sibling component. Basically, I have a Bootstrap row with two columns. In one column I have an input form (Quill Editor) with a button, and in the other column, the Tabulator table. When I click the button in the Input form column I need to add data from the input form to the Tabulator table in the other column. I want to use the Tabulator addRow method in the input form component when the button is clicked to add a row on the Tabulator component. For that i'm using Refs. The thing is that I knew that I can't use the Tabulator Ref outside the Tabulator component to call the addRow method, so I can't figure out how to get a workaround this problem. I know I can change the state of the Tabulator component (I already figured out how to do that), but I don't want the component to re-render each time I add data. Here's my code, and any help or ideas would be highly appreciated:

import React, { useEffect, useState, useRef } from "react";
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'react-bootstrap/Button';
import ReactQuill from 'react-quill';
import { ReactTabulator, ReactTabulatorOptions, ColumnDefinition } from 'react-tabulator';


import 'bootstrap/dist/css/bootstrap.min.css';
import 'react-quill/dist/quill.snow.css';
import 'react-tabulator/lib/css/tabulator.min.css';
import 'react-tabulator/lib/styles.css';
import '../../../css/zellero.css';
import '../../../css/zelleroTabulator.css';
import _ from 'lodash';
import moment from 'moment';



function QuillInput(props) {

        return (
            <Container>
                <ReactQuill theme="snow" value={props.value}/>

                <Row>
                    <Col></Col>
                    <Col>
                        <Button variant="one bc-4284f7" onClick={() => { notesTableRef.addRow({noteID: '123', noteText: quillRef.current.editor.root.innerHTML, date: "14/04/2022"}) }}>Add</Button>
                    </Col>
                </Row>
            </Container>
        );
  };

    function NotesTable(props) {

        const setShowQuillEditor = props.setShowQuillEditor;
        const setQuillValue = props.setQuillValue;

        const options = { height: '300px', selectable: 1, headerVisible: false, autoResize: false, index: "noteID", layoutColumnsOnNewData:true, };
        
        let dateFormatterOne = (string, fontSize, backgroundColor) => { return ` <div class="container h-100"> <div class="row align-items-center h-100"> <div class="col-sm-12 mx-auto"> <a class="aTagOne" style="background: ${backgroundColor}; font-size: ${fontSize}">${string}</a> </div> </div> </div> `; };
        
        const notesTableRef = useRef(null);

        const columns = [
            { field: "noteID", visible: false, resizable: false },
            {
                field: "noteText",
                formatter: (cell) => { cell.getElement().style.whiteSpace = "pre-wrap"; cell.getElement().classList.add("tabulatorCellOne"); let item = cell.getValue().replace(/<(.|\n)*?>/g, ''); return _.truncate(item, { "length": 40}) },
                editable: false,
                resizable: false,
                variableHeight: true,
                width: "70%"
            },
            { field: "date", width: "30%", editable: false, resizable: false, formatter: (cell) => dateFormatterOne(moment(cell.getValue()).format('DD/MM/YYYY'), "small", "#00cc6f")},
          ];
        
        return (
            <div className="infoModalTable">  
                < ReactTabulator
                data = { props.data }
                columns = { columns }
                layout = { "fitColumns" }
                options = {options}
                onRef={(r) => (notesTableRef.current = r.current)}
                events = {
                    {
                        rowSelected: (row) => { setShowQuillEditor(false); setQuillValue(row.getData().noteText) },
                        rowDeselected: (row) => { setShowQuillEditor(true); setQuillValue(row.getData().noteText) }
                    }
                }
                /> 
            </div>
        );
      }


function NotesTabDiv(props) {
    
    const [showQuillEditor, setShowQuillEditor] = useState(true);
    const [quillValue, setQuillValue] = useState('');


    return (
        <Container className="tabPaneDiv">
            <Row>
                <Col>
                    <div>
                        <QuillInput showQuillEditor={showQuillEditor} value={quillValue} />
                    </div>
                </Col>
                <Col className="infoModalBox">
                    <NotesTable data={props.notesArray} setQuillValue={setQuillValue} setShowQuillEditor={setShowQuillEditor} /> 
                </Col>
            </Row>
        </Container>
    );
  };
  
  export default NotesTabDiv
  


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source