0

I am working on a Drag and Drop scenario with react-beautiful-dnd, trying to add a drop animation, following the manual https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/drop-animation.md.

Using typescript I am getting in trouble when I add a isDragging property to a simple div element. Trying to work around this problem I was building a component with extended properties, following

Specify specific props and accept general HTML props in Typescript React App

This worked to some point, but is failing on the ref property.

My code:

interface IdragDiv extends React.HTMLAttributes<HTMLDivElement>, React.RefAttributes<HTMLDivElement> {
  isDragging: boolean;
}
export class DragDiv extends React.Component<IdragDiv> {
  render() {
    const { children, ...rest } = this.props;
    return <div {...rest}>{children}</div>;
  }
}

Calling it like this:

...
          return (
            <Draggable
              draggableId={...}
            >
              {(provided, snapshot) => {
                return (
                  <DragDiv
                    {...className}
                    ref={provided.innerRef}
                    {...provided!.draggableProps}
                    {...provided!.dragHandleProps}
                    isDragging={snapshot.isDragging && !snapshot.isDropAnimating}
                  >
                    ...
                  </DragDiv>
                );
              }}
            </Draggable>
          );
...

This results in following error:

(property) ref?: (string & ((instance: HTMLDivElement | null) => void)) | (string & React.RefObject<HTMLDivElement>) | (((instance: DragDiv | null) => void) & ((instance: HTMLDivElement | null) => void)) | ... 4 more ... | undefined

No overload matches this call.
  Overload 1 of 2, '(props: Readonly<IdragDiv>): DragDiv', gave the following error.
    Type '(element?: HTMLElement | null | undefined) => any' is not assignable to type '(string & ((instance: HTMLDivElement | null) => void)) | (string & RefObject<HTMLDivElement>) | (((instance: DragDiv | null) => void) & ((instance: HTMLDivElement | null) => void)) | ... 4 more ... | undefined'.
      Type '(element?: HTMLElement | null | undefined) => any' is not assignable to type 'string & ((instance: HTMLDivElement | null) => void)'.
        Type '(element?: HTMLElement | null | undefined) => any' is not assignable to type 'string'.
  Overload 2 of 2, '(props: IdragDiv, context?: any): DragDiv', gave the following error.
    Type '(element?: HTMLElement | null | undefined) => any' is not assignable to type '(string & ((instance: HTMLDivElement | null) => void)) | (string & RefObject<HTMLDivElement>) | (((instance: DragDiv | null) => void) & ((instance: HTMLDivElement | null) => void)) | ... 4 more ... | undefined'.
      Type '(element?: HTMLElement | null | undefined) => any' is not assignable to type 'string & ((instance: HTMLDivElement | null) => void)'.
        Type '(element?: HTMLElement | null | undefined) => any' is not assignable to type 'string'.

Any ideas, is there another way to solve this problem?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
o-faro
  • 789
  • 8
  • 16

1 Answers1

-2

You should be able to use createRef() in your code like this:

class Foo extends Component {
  private myRef = createRef<HTMLDivElement>();

  render() {
    return <div ref={this.myRef} />
  }
}

This is simplified ofc, but that should fix the error you are encountering.

Possibly this will fix it for react-beautiful-dnd then, by creating your own ref prop for the DragDiv you have:

class DragDiv extends React.Component {
  render() {
    return (
      <div {...this.props} ref={this.props.innerRef}></div>
    );
  }
}

Then in your Draggable:

return (
  <Draggable draggableId={...}>
    {(provided, snapshot) => {
      return (
        <DragDiv
          {...className}
          innerRef={provided.innerRef}
          ...

See if that fixes it for you.

rrd
  • 5,789
  • 3
  • 28
  • 36
  • Not in this scenario. The ref is provided by react-beautiful-dnd and must be called like I did. ref={provided.innerRef} – o-faro Oct 11 '19 at 10:10
  • Updated the answer @smaug333 see if that can help? – rrd Oct 11 '19 at 10:16
  • Thank you for your answer. The problem is not how to add a ref to an element. Problem here is to find the right typing. I was trying to add a property "isDragging", which is not known by react/typescript. Skipping typescript my code would doubtlessly work fine – o-faro Oct 11 '19 at 10:29
  • Maybe instead of HTMLDivElement you should try HTMLElement - the error you are experiencing seems to focus on that. Also that error is pointing at ref being the issue, not isDragging. – rrd Oct 11 '19 at 10:41
  • The isDragging Problem was already solved. It must be a HTMLDivElement, only HTMLElement leads to errors in the DragDiv-Definition. – o-faro Oct 11 '19 at 10:51