类型 ref 不可分配给类型 IntrinsicAttributes

7 javascript typescript reactjs

我想对我的元素使用 ref,但出现错误,并且不知道如何修复它。

Type '{ ref: RefObject<unknown>; letter: string; draggable: number; }' is not assignable to type 'IntrinsicAttributes & content'.
  Property 'ref' does not exist on type 'IntrinsicAttributes & content'. 
Run Code Online (Sandbox Code Playgroud)

我在网上搜索了一段时间,但找不到任何对我的情况有帮助的信息。

这是我的代码:

Content.tsx
import React, { useRef, useState } from 'react';
import { Box } from './Box';

function Content() {
    const onSubmitAnswer = () => {
        console.log("da");
    };

    const test = React.createRef();
    
    return (
        <div>
            <Box {...{ letter: 'C', draggable: 1 }} ref={test}/>
            <Box {...{ letter: 'A', draggable: 0 }} />
            <Box {...{ letter: 'B', draggable: 0 }} />
            <Box {...{ letter: 'C', draggable: 0 }} />
            <Box {...{ letter: 'D', draggable: 0 }} />
            <button onClick={onSubmitAnswer}>Trimite!</button>
        </div>
    );
}

export default Content;
Run Code Online (Sandbox Code Playgroud)

和 Box.tsx

import React from 'react';
import './Box.css';
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';

export type content = {
    letter: string,
    draggable: number
}



export function Box(props: content) {
    const el = React.createRef();

    if(props.draggable) {
        return (
            <Draggable>
            <div className="box box-drag">
                <span className="box-content">
                  {props.letter}
                </span>
              </div>
            </Draggable>
            );
    }
    return (
        <div className="box">
            <span className="box-content" ref={el => {console.log(el?.getBoundingClientRect());}}>
              {props.letter}
            </span>
          </div>
        );
}
Run Code Online (Sandbox Code Playgroud)

我想我知道为什么会发生这种情况 - Box 是一个组件,当我将 ref 作为属性传递时(就像我对 JSX 标签所做的那样),它的行为不一样(它位于 props 中)。

有没有办法在组件上使用 ref/className/name 就像我在 JSX 元素上使用它们一样?

//编辑:打字稿操场链接:

https://www.typescriptlang.org/play?ssl=1&ssc=1&pln=1&pc=7#code/JYWwDg9gTgLgBAJQKYEMDGMA0cDecCuAzksgGbZFIDKMKMScAvnKVBCHAORSoacDcAKFCRYXAHQB6AEIQAHuLSFCA4eGjwAIlBQBzXSgBGAGyTY82vQZNJNdFNkv6jpgKIA3JADt4zVuy4edBgAWgATHWcbVUEYAE8wBjQIH294AF5cQTgcuFMYeigALjhCGChgL11MbNyIqxckEq98EEMkKEFGQUFSfC8MYBS4WTkACjA2MEIS5NSfAEos3LhgUgmpwnF6qNMlnFqVnJ4YfCgvODHDo5WAHidrUwA+a5uc27Dgdzg0YxRlAByKBASHSACJDPI4JC5OFImCXm8kXBboQwCgLr9-oQgSDwTCQnN6D4Ea9kSscJMINNxPlCt1yTdbpI0RjEYz3pJPu52eTmQ9GrzkQshCsGbkTmcLlckR8vj8-oDgaCIfJSRzUejMYqccr8fJCSliTB1RzcFSaXSOuK+SytUKmVyvg7ciKuj0+gMYEMLgBhI1pMb7a5zMpwFJUfCGEDAGAAQS8hAA7h04Jkg2mnss3qGIKZaRBdGMwWEUGC3WKhCGUmH6GHMshgoogvQyLcMXEnkHRblrpLzpcye9uS6maNcOJJ3grcUuL7ONgdo8mnAAIxMZg8UjpHB1mDMSSjo63cc4SfiadIAodEqcOMLuBLxolAAMG7gh6Hx9P58v19nnDSA+T42K+76fhqP5TnkV6FLe86LpEy5gYwB5HncUEXjB-63powFIc+cBvqhH7obktyGPgBTDCkvrGMAaAANY7hGUYxvGiYplAjBPAAKhU7FIAAhMylHUV4R7MiO1xut0ghIHIojwGESCkCg+DGPA-rzDA-BAA
Run Code Online (Sandbox Code Playgroud)

cap*_*ian 6

如果你想使用ref,你应该包装BoxforwardRef

import React, { useRef, useState } from 'react';
import './Box.css';
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';

type content = {
  letter: string,
  draggable: number
}

const Box = React.forwardRef<HTMLDivElement, content>((props, ref) => {
  if (props.draggable) {
    return (
      <Draggable>
        <div className="box box-drag">
          <span className="box-content">
            {props.letter}
          </span>
        </div>
      </Draggable>
    );
  }
  return (
    <div className="box">
      <span className="box-content">
        {props.letter}
      </span>
    </div>
  );
});



function Content() {
  const onSubmitAnswer = () => {
    console.log("da");
  };

  const test = React.createRef<HTMLDivElement>();

  return (
    <div>
      <Box {...{ letter: 'C', draggable: 1 }} ref={test} />
      <Box {...{ letter: 'A', draggable: 0 }} />
      <Box {...{ letter: 'B', draggable: 0 }} />
      <Box {...{ letter: 'C', draggable: 0 }} />
      <Box {...{ letter: 'D', draggable: 0 }} />
      <button onClick={onSubmitAnswer}>Trimite!</button>
    </div>
  );
}

export default Content;
Run Code Online (Sandbox Code Playgroud)

操场

ref期望是 HTML 元素。这就是为什么我已经提供HTMLDivElementconst test = React.createRef<HTMLDivElement>();。它应该是哪个 HTML 元素由您决定。

Box被包含在forwardRef显式的泛型参数中:React.forwardRef<HTMLDivElement, content>