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

问题描述 投票:0回答:4

我试图让 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>
  );
}

这里是playground链接,来自其他堆栈溢出帖子,似乎我只需要在初始化useRef obj时传递null类型。

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

reactjs typescript flowtype
4个回答
50
投票

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

const unblockRef = useRef<() => void | null>(null);

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

所以,你需要确保它是一个 函数或 null:

const unblockRef = useRef<(() => void) | null>(null);

19
投票

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

React.RefObject
React.MutableRefObject

你的 testRef 语法有效( | null )是关键......

  const testRef = useRef<string | null>(null);

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

testRef.current = "some string";

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

const unblockRef = useRef<(() => void) | null>(null);

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

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

const unblockRef:React.MutableRefObject<(() => void)| null> = useRef<(() => void) | null>(null);

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


8
投票

您的问题是您如何使用

|
运算符。即,该类型的优先级:

() => void | null

其实是

() => (void | null)

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

const unblockRef = useRef<(() => void) | null>(null);

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


1
投票

多个类型分配给变量时,如果其中一种类型是回调,则必须将回调包装在其自己的一组括号中。

const unblockRef = useRef<(() => void) | null>(null);

这是因为您可以从一个函数返回多种类型。因此,从逻辑上讲,TypeScript 认为您的函数将返回

void
null
- 而不是 just void。

© www.soinside.com 2019 - 2024. All rights reserved.