【问题标题】:A spread argument must either have a tuple type or be passed to a rest parameter React扩展参数必须具有元组类型或传递给剩余参数 React
【发布时间】:2021-10-16 11:53:11
【问题描述】:

我在Typescript中有这个代码:

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

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

setHistory(...newHistory);

我有错误:

展开参数必须要么具有元组类型,要么被传递给休息参数。

有人可以帮助我吗,我怎样才能正确输入这个?

【问题讨论】:

    标签: reactjs typescript spread


    【解决方案1】:

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

    setHistory(...newHistory); //drops error
    
    setHistory.apply(null, newHistory) //works
    

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

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

    【讨论】:

      【解决方案2】:

      简单地说:

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

      const newObject = [...newHistory];
      setHistory(newObject);
      
      // or, even simpler: 
      setHistory([...newHistory]);
      
      // NOT the below - this is passing in multiple arguments.
      setHistory(...newHistory);
      

      【讨论】:

      • 咦,为什么是对象?
      • 糟糕——忘记了 OP 处理的是数组而不是对象。 (它也适用于对象。)谢谢,@Sulthan,很好!
      【解决方案3】:

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

      如果打算总是修改以前的状态,我会打电话给setHistory(previousHistory => previousHistory.slice(x, y))

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

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

      【讨论】:

        猜你喜欢
        • 2021-11-09
        • 2020-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        • 2014-11-14
        • 2021-07-20
        相关资源
        最近更新 更多