2
votes

I am trying to export a react but getting this TS error which I am unable to resolve.

Here is the component:

import React, {
  useEffect,
  MutableRefObject,
  forwardRef,
  RefObject
} from 'react';
import styled from 'styled-components';

export interface TextareaInputProps
  extends React.HTMLAttributes<HTMLTextAreaElement> {
  text?: string;
  onChange: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
  onApprove?: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
}

export interface StyledTextareaInputProps {
  ref: MutableRefObject<HTMLTextAreaElement | null>;
}

const StyledTextArea = styled.textarea<StyledTextareaInputProps>`
  display: flex;
  align-items: stretch;
  resize: none;
  flex: 1;
  padding: ${({ theme }) => theme.padding.md}px;
  color: ${({ theme }) => theme.colors.grey700};
  line-height: ${({ theme }) => theme.lineHeights.nm};
  font-family: ${({ theme }) => theme.fontFamilies.regular};
  font-size: ${({ theme }) => theme.fontSizes.nm}px;
  font-weight: ${({ theme }) => theme.fontWeights.regular};
  text-overflow: ellipsis;
  border-style: none;
  border-color: transparent;
  overflow: auto;
`;

const TextareaInput = (
  { text, onChange, onBlur, onKeyDown, ...otherProps }: TextareaInputProps,
  ref: RefObject<HTMLTextAreaElement>
) => {
  useEffect(() => {
    if (ref && ref.current) {
      ref.current.focus();
    }
  }, [ref]);
  return (
    <StyledTextArea
      ref={ref}
      {...otherProps}
      onChange={onChange}
      value={text}
      onBlur={onBlur}
      onKeyDown={onKeyDown}
    />
  );
};

export default forwardRef(TextareaInput);

This is the error I am getting:

Argument of type '({ text, onChange, onBlur, onKeyDown, ...otherProps }: TextareaInputProps, ref: React.RefObject) => JSX.Element' is not assignable to parameter of type 'ForwardRefRenderFunction<HTMLTextAreaElement, TextareaInputProps>'. Types of parameters 'ref' and 'ref' are incompatible. Type 'MutableRefObject<HTMLTextAreaElement | null> | ((instance: HTMLTextAreaElement | null) => void) | null' is not assignable to type 'RefObject'. Type 'null' is not assignable to type 'RefObject'.

I have other components with a similar pattern which all works.

1

1 Answers

0
votes

If you read react documentation about forwardRef:

The second ref argument only exists when you define a component with React.forwardRef call. Regular function or class components don’t receive the ref argument, and ref is not available in props either.

You need to do something like this:

const TextareaInput = (
  { text, onChange, onBlur, onKeyDown, ...otherProps }: TextareaInputProps,
  ref: RefObject<HTMLTextAreaElement>
) => {
  useEffect(() => {
    if (ref && ref.current) {
      ref.current.focus();
    }
  }, [ref]);
  return (
    <StyledTextArea
      ref={ref}
      {...otherProps}
      onChange={onChange}
      value={text}
      onBlur={onBlur}
      onKeyDown={onKeyDown}
    />
  );
};

First create ref:

const ref = React.createRef();

Second pass ref using forwardRef:

const ModifiedTextareaInput = React.forwardRef((props, ref) => <TextareaInput {...props} ref={ref}/>);
export default ModifiedTextareaInput;

Note: I have not added type defination for those. Assuming you can add those