【问题标题】:Typescript useState React Hook Destructuring Error (Not Returning Array?)Typescript useState React Hook 解构错误(不返回数组?)
【发布时间】:2021-06-30 15:07:40
【问题描述】:

我第一次尝试使用一个简单的 React 应用程序,并希望设置一个简单的 MVC 来连接 ASP.NET 后端,所有这些都是在 Visual Studio 2019 中完成的(这让 React 有些头疼)。但是,现在我正在尝试实现模型,我发现所有强类型化 useState 挂钩的建议都对我不起作用。

根据this onethis one 之类的一些教程,它应该像在括号中添加一个类型一样简单,例如const [state, setState] = useState<Type>({}),因为它具有通用实现。不幸的是,对我来说,这会引发错误“Uncaught TypeError: Invalid attempt to destructure non-iterable instance.

该线程here 建议通过将 [] 更改为 {} 从数组切换到对象,但这只会使我传递的两个参数未定义,因此我没有状态或方法来更新所述状态。

我一直在阅读,直到我对数组解构有了一个简要的了解,所以我明白这个想法是传递一个包含两个常量的数组,这两个常量将按顺序分配 useState 返回的数组元素钩。因此,我尝试手动解构数组,分别设置常量useState[0]useState[1]。当我为无类型的钩子尝试这个时,它按预期工作。当我为 typed hook 尝试这个时,我得到了一些关于没有元素的错误,并且在打印出对象时,发现不是像 untyped hook 这样的数组,而是一个布尔值。似乎类型化的 useState 返回值“false”而不是数组。

在这一点上,我最好的猜测是我有一些依赖项没有实现类型化的 useState,但我在故障排除方面确实遇到了障碍。有人知道我做错了什么吗?

编辑:我设置的测试文件 -

import React, { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import { Product } from '../Models/Product';

const Account = () => {
    //Works as-intended
    const test = useState(5);
    //Returns false when logged
    const test2 = useState<Product>({
        "ProductID": "p#corn", "Description": "Delicious corn", "ImageLink": "https://testlink.com", "Name": "Corn", "Price": "2.99", "Category": "Food"
    });
    
    //What should work, to my understanding, however this makes the route crash when it's navigated to because of the "Inavlid attempt to destructure non-iterable instance
    const [test3, setTest] = useState<Product>({});

    function clickHandler() {
        console.log(test)
    }

    function clickHandler2() {
        console.log(test2)
    }

    return (
        <div className='wrapper'>
            <button onClick={clickHandler}>Test</button>
            <button onClick={clickHandler2}>Test2</button>
        </div>
    )
}

export default Account;

产品模型 -

 export interface Product {
    ProductID: string;
    Description: string;
    ImageLink: string;
    Name: string;
    Price: string;
    Category: string;
    }

【问题讨论】:

  • 你能分享你的代码吗?如果无法进行调查,很难想象其他代码可能会导致这个错误。您的 useState 导入来自哪里,它在哪里被调用。添加类型不应该真正改变打字稿转译的javascript代码,它只会改变编译器是否允许它没有错误。
  • @cefn 虽然我一直是个潜伏者,但这是第一次真正发帖,所以我不完全确定做事的正确方法。我将它添加为代码 sn-p,但如果效果更好,我可以做截图。我也没有包含任何配置文件,但我在 package.json 中有 React 17.0.2,所以我猜这就是导入的内容。感谢您的观看!
  • 更奇怪的是,正如你所说的第一行 useState 做了你认为的意图,因为它应该返回一个数组,首先包含一个值,然后是一个 setter,而不是一个值。我开始怀疑您的环境是否设置了一些 JSX 配置,这意味着它根本没有将 &lt;Product&gt; 解释为 typescript Generic,而是其他东西,比如 HTML 元素或其他东西。它当然似乎特定于您的环境或配置。我将整理一个 CodeSandbox,这可能是您了解世界其他地方的真实情况的好方法。
  • 使用console.log(useState&lt;Product&gt;({}))时会打印什么;
  • @cefn 不仅是 &lt;Product&gt;,它还有更通用的类型,如 &lt;Number&gt;&lt;Boolean&gt;,但 JSX 配置似乎确实是罪魁祸首,因为我不得不从几个不同的教程拼凑而成。

标签: reactjs typescript use-state


【解决方案1】:

这是a CodeSandbox 的示例,该示例与您的案例有些相关,它演示了 useState 如何在其他人的机器上工作。

正如您从测试它和弄乱我分享的示例中看到的那样,指定泛型类型的 useState 应该很好,而且表现得如您所愿。

这强调了您的本地机器或项目环境对您来说有些特殊。

import React, { useCallback, useState } from "react";

import "./styles.css";

interface Product {
  Name: string;
  Price: number;
}

const productA = {
  Name: "Corn",
  Price: 2.99
};

const productB = {
  Name: "Frozen Orange Juice",
  Price: 10_000
};

export default function Show() {
  const [product, setProduct] = useState<Product>(productA);

  const toggleProduct = () =>
    setProduct(product === productA ? productB : productA);

  return (
    <div className="App" onClick={toggleProduct}>
      <h1>{product.Name}</h1>
      <h2>{product.Price}</h2>
    </div>
  );
}

既然您问到如何获得最佳响应...

理想情况下,在发布时尝试创建其他人可以看到失败的问题案例。如果您尝试执行此操作(例如使用 CodeSandbox)但它在那里工作正常,那么您需要清理您自己的本地环境,直到您弄清楚您的设置有什么独特之处会使您的代码中断但没有 -还有一个。

理想情况下,如果您无法在单个页面复制(沙箱)中创建它,因为它与您的项目结构有关,请通过在 github 上公开共享实际项目结构及其代码和配置来创建可运行的复制,以便人们可以通过检查并构建/运行它来重现您的问题。这样他们很快就能找到您项目的独特之处。

通常,这个创建重现的过程会帮助您找出问题所在 - 例如。你从 https://create-react-app.dev/docs/adding-typescript/ 的 vanilla create-react-app typescript 骨架开始填充一个空白的 github 存储库,然后你的问题案例突然开始在那里工作 - 现在你有一个基础,可以通过将项目的特殊功能添加到简单的 repro 来分割你的问题直到它破裂。

【讨论】:

  • 啊!感谢您提供的示例和有关制作好帖子的信息。我仍然不知道很多用于良好代码共享的工具,所以我将尝试更多地了解 CodeSandbox 并看看创建一个公共 github 存储库,以便我可以缓慢地重新创建我的项目,直到该功能中断,如果我无法弄清楚我在配置中出错的地方,请分享它。
猜你喜欢
  • 1970-01-01
  • 2019-08-29
  • 2022-01-11
  • 2021-04-03
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-04
相关资源
最近更新 更多