Search code examples
office-ui-fabricfluent-ui

How to use React refs inside FluentUI DetailsList onRender function


I need to use a ref inside the onRender function of a FluentUI DetailsList column. But If I try to use a string ref: e.g: ref={"myref"} React complains that react-dom.development.js:13381 Uncaught (in promise) Error: Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here:..... And if I try to use useRef I get an error that the onRender function is not a functional component. How can I use refs (multiple) in the FluentUI DetailsList onRender function?


Solution

  • There are several ways to override the rendering of rows/columns within DetailsList.

    To define new content for a column, the easiest way is to define an onRender value in the column definition. For instance, in this snippet column3 has a function called every time it renders cells in that column.

    const _columns = [
          { key: 'column1', name: 'Name', fieldName: 'name', minWidth: 100, maxWidth: 200, isResizable: true },
          { key: 'column2', name: 'Value', fieldName: 'value', minWidth: 100, maxWidth: 200, isResizable: true },
          { key: 'column3', name: 'Custom value with ref', fieldName: 'value', minWidth: 100, maxWidth: 200, onRender: renderColumn3 },
        ];
    

    The onRender callback is called with the original item, the index in the list, and the column definition. From there it's trivial to return a react component, which can use any hooks it needs (such as useRef).

    This example renders a very simple component that uses refs:

    const MyControlForColumn3 = props => {
      const myRef = React.useRef();
    
      return <div ref={myRef}><button onClick={() => console.log(myRef.current)}>Print ref.current to console</button>{props.children}</div>;
    }
    
    const renderColumn3 = (item: any, itemIndex: any, columnDefinition: any) => {
      return <MyControlForColumn3>Item #{itemIndex}</MyControlForColumn3>
    }
    

    (Full working example on codepen)