无法分配给“当前”,因为它是只读属性

Sea*_*Liu 38 typescript reactjs flowtype

我试图让 useRef obj 为 null 或函数,这里是代码片段

import "./styles.css";
import { useState, useRef, useEffect } from "react";
export default function App() {
  const testRef = useRef<string | null>(null);
  const unblockRef = useRef<() => void | null>(null);

  useEffect(() => {
    const test = () => {
      console.log("hey");
    };

    testRef.current = "";

    // this would give the error code
    unblockRef.current = null;
    // unblockRef.current = "saddsa";
  }, []);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Run Code Online (Sandbox Code Playgroud)

这是来自其他堆栈溢出帖子的游乐场链接,看起来我只需要在初始化 useRef obj 时传递 null 类型。

我用 testRef 测试逻辑,效果很好,似乎如果 useRef 类型是函数就会带来麻烦,感谢您的任何帮助!

tec*_*yle 46

这只是一个 TypeScript 错误。你的语法有问题:

const unblockRef = useRef<() => void | null>(null);
Run Code Online (Sandbox Code Playgroud)

这被解释为返回 void 或 null 的函数

因此,您需要确保它是一个函数或 null

const unblockRef = useRef<(() => void) | null>(null);
Run Code Online (Sandbox Code Playgroud)


Pao*_*ati 10

ref 有两种类型:可变或不可变

React.RefObject
React.MutableRefObject
Run Code Online (Sandbox Code Playgroud)

你的 testRef 工作语法 ( | null ) 是关键......

  const testRef = useRef<string | null>(null);
Run Code Online (Sandbox Code Playgroud)

这样你就隐式创建了一个 React.MutableRefObject 并可以分配

testRef.current = "some string";
Run Code Online (Sandbox Code Playgroud)

在另一种情况下,由于语法不正确,unblockRef 只是 React.RefObject,如其他答案所述。由于运算符优先级,您必须使用括号。

const unblockRef = useRef<(() => void) | null>(null);
Run Code Online (Sandbox Code Playgroud)

无论如何,也可以使用显式声明:

const testRef:React.MutableRefObject<string | null> = useRef<string | null>(null);

const unblockRef:React.MutableRefObject<(() => void)| null> = useRef<(() => void) | null>(null);
Run Code Online (Sandbox Code Playgroud)

这里有一篇很好的解释文章


rom*_*lem 8

您的问题是您如何使用|运算符。即,该类型的优先级:

() => void | null
Run Code Online (Sandbox Code Playgroud)

实际上是

() => (void | null)
Run Code Online (Sandbox Code Playgroud)

如果添加一些显式括号来使类型

const unblockRef = useRef<(() => void) | null>(null);
Run Code Online (Sandbox Code Playgroud)

然后你就可以重新分配它。