Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support forwarding refs to cell components, allowing access to the DOM element rendered by the cell. #726

Closed
gersongoulart opened this issue Aug 14, 2024 · 3 comments · Fixed by #727
Assignees

Comments

@gersongoulart
Copy link
Contributor

Current Behavior

Currently, to grab a hold of a table cell DOM element, developers must use React.findDOMNode to find the browser DOM node for a React class component instance. This API is deprecated and will be removed in a future major version of React. See the alternatives.

Expected Behavior

Developers should be able to pass a ref to the DataCell (FixedDataTableCellDefault) component, enabling external access to the underlying DOM element of the cell.

By forwarding the ref, you can now perform operations such as focusing the cell, measuring its dimensions, or integrating it with other libraries that require direct DOM interaction. To use this feature, we would simply pass a ref prop to the DataCell component, and it will be attached to the top-level div element rendered by the cell. This enhancement provides greater flexibility and control when working with table cells in the application without relying on deprecated APIs.

Example usage:

import { DataCell } from 'fixed-data-table-2';

export function EditableCell(props) {
  const { viewComponent: View, editComponent: Edit, ...cellProps } = props;
  const cellElement = useRef(null);
  const view = useViewCell(cellProps);
  const edit = useEditCell(cellProps);
  const Component = edit.isEditing ? Edit : View;

  return (
    <DataCell
      ref={cellElement} // this will save a reference to the underlying DOM node...
      onClick={edit.onEdit}
      >
      <Component
        {...cellProps}
        {...view}
        {...edit}
        cellElement={cellElement} // ...which can now be used by other components for interaction.
      />
    </DataCell>
  );
}

Possible Solution

Since this project is on React v17+, the simplest way to accomplish this, is to convert the (FixedDataTableCellDefault) component to a function-style component with forwardRef.

Example:

const FixedDataTableCellDefault = React.forwardRef(function FixedDataTableCellDefault(props, ref) {
  // Same code as before.
});

FixedDataTableCellDefault.propTypes = {/* propTypes gotta live out here */}

export default FixedDataTableCellDefault;

Context

As I work to upgrade my project's codebase in preparation for React v19, I am attempting to resolve all issues that could prevent the upgrade, and the reliance on React.findDOMNode is one of them.

@pradeepnschrodinger
Copy link
Collaborator

@gersongoulart , the proposed solution sounds reasonable to me.
Feel free to put in a PR for this.

gersongoulart pushed a commit to provantagex/fixed-data-table-2 that referenced this issue Aug 15, 2024
…allowing for external control or access to the DOM element rendered by the cell.

- Refactored the component to function-style so as to utilize `React.forwardRef`, enabling the ability to pass a `ref` to the cell component
- Ensured that the `ref` is attached to the top-level `div` element rendered by the cell, enabling usage of ref-based methods or direct DOM manipulation.
- Maintained existing prop-types while supporting the new `ref` forwarding functionality.
- Verified that existing usage patterns of the component remain unaffected by these changes.
@pradeepnschrodinger
Copy link
Collaborator

Fixed with v2.0.13 via #727.

Client's can now pass ref to the DataCell renderer to grab the top-level DOM node.
eg:

import { DataCell } from 'fixed-data-table-2';

export function CustomCell(props) {
  const cellElement = useRef(null);

  return (
    <DataCell
      {...props}
      ref={cellElement} // this will grab a reference to the underlying DOM node...
    >
      <CustomComponent
        {...props}
        cellElement={cellElement} // ...which can now be used by other components for interaction.
      />
    </DataCell>
  );
}

@pradeepnschrodinger
Copy link
Collaborator

@gersongoulart, I'm closing this thread since the issue is resolved, but feel free to comment if we missed anything.

And good luck with the React v19 upgrade. Let us know if you face any blockers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants