扩展参数必须具有元组类型或传递给 React 的剩余参数

Mat*_*ski 73 spread typescript reactjs

我有这个代码Typescript

const [history, setHistory] = useState([Array(9).fill(null)]);
Run Code Online (Sandbox Code Playgroud)
const newHistory = history.slice(0, currentStep + 1);
Run Code Online (Sandbox Code Playgroud)

当我想使用这样的扩展运算符设置新状态时:

setHistory(...newHistory);
Run Code Online (Sandbox Code Playgroud)

我有错误:

扩展参数必须具有元组类型或传递给剩余参数。

有人可以帮助我,我如何正确输入这个?

And*_*ndy 42

简单来说:

因为您直接使用扩展运算符,所以您向函数传递了多个参数useState,但useState函数只接受单个参数。相反,使用扩展运算符创建单个数组并将其传入。

const newObject = [...newHistory];
setHistory(newObject);

// or, even simpler: 
setHistory([...newHistory]);

// NOT the below - this is passing in multiple arguments.
setHistory(...newHistory);
Run Code Online (Sandbox Code Playgroud)

  • 糟糕 - 忘记了 OP 处理的是数组而不是对象。(它也适用于对象。)谢谢,@Sulthan,很好! (2认同)

Mik*_*ike 38

一般来说,您可以通过使用 apply 来避免此类错误

setHistory(...newHistory); //drops error

setHistory.apply(null, newHistory) //works
Run Code Online (Sandbox Code Playgroud)

但在您的示例中存在一个问题:您初始化历史记录,[[null, null, null...]] 然后获取它,切片[[null, null, ...], ...] 并尝试将其设置回setHistory([null, null], null)

看来你只需要使用setHistory(newHistory);

  • 在类构造函数中调用“super()”怎么样?那么你不能使用“apply” (3认同)

小智 23

这对我来说非常有效!

setHistory(...(newHistory as []));
Run Code Online (Sandbox Code Playgroud)


And*_*ant 1

使用时useState1返回的元组中的索引为setHistory。那应该只接受一个参数(新值)。原始帖子中的示例将历史分为可能的 8 个参数。它需要作为数组传递,可以像 一样简单setHistory(newHistory)

如果目的是始终修改以前的状态,我会调用setHistory(previousHistory => previousHistory.slice(x, y)).

还!对于 Typescript,您需要像这样为 useState 声明一个类型useState<History[]>(Array(9).fill(null));如果没有声明类型,Typescript 将推断出一些在这种情况下可能不是您想要的东西。

请注意,您并不总是需要声明 useState 的类型。实际上,我鼓励尽可能使用类型推断。如果初始值为 null 或未定义,您将无法在 Typescript 中使用类型推断。