Reactjs Typescript useState React钩子分解结构错误(不返回数组?)
我第一次尝试使用一个简单的React应用程序,并希望建立一个简单的MVC来连接ASP.NET后端,所有这些都是在Visual Studio 2019中完成的(这让React有些头疼)。然而,现在我正在尝试实现模型,我发现所有关于强类型useState钩子的建议对我都不起作用 根据一些教程,比如or,它应该像在括号中添加类型一样简单,比如Reactjs Typescript useState React钩子分解结构错误(不返回数组?),reactjs,typescript,use-state,Reactjs,Typescript,Use State,我第一次尝试使用一个简单的React应用程序,并希望建立一个简单的MVC来连接ASP.NET后端,所有这些都是在Visual Studio 2019中完成的(这让React有些头疼)。然而,现在我正在尝试实现模型,我发现所有关于强类型useState钩子的建议对我都不起作用 根据一些教程,比如or,它应该像在括号中添加类型一样简单,比如const[state,setState]=useState({}),因为它有一个通用实现。不幸的是,对我来说,这抛出了一个错误“未捕获的TypeError:对不
const[state,setState]=useState({})
,因为它有一个通用实现。不幸的是,对我来说,这抛出了一个错误“未捕获的TypeError:对不可编译实例进行破坏的尝试无效。”
该线程建议通过将[]更改为{}来从数组切换到对象,但是这只会使我传递的两个参数未定义,因此我没有状态或方法来更新所述状态
我一直在阅读,直到我对数组的解构有了一个简单的了解,所以我知道这个想法是传递一个带有两个常量的数组,这两个常量将按照useState钩子返回的数组元素的顺序分配。因此,我尝试手动分解数组,分别设置常量useState[0]
和useState[1]
。当我在一个非类型的钩子上尝试这个方法时,它如预期的那样工作。当我对类型化钩子尝试这个方法时,我得到了一些关于没有元素的错误,并且在打印出对象时,发现不是像非类型化钩子那样的数组,而是一个布尔值。类型化的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;
这里有一个与您的案例相关的示例,它演示了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>
);
}
import React,{useCallback,useState}来自“React”;
导入“/styles.css”;
接口产品{
名称:字符串;
价格:数量;
}
const productA={
名称:“玉米”,
售价:2.99
};
const productB={
名称:“冷冻橙汁”,
价格:万元
};
导出默认函数Show(){
const[product,setProduct]=useState(productA);
常量切换产品=()=>
setProduct(product==productA?productB:productA);
返回(
{product.Name}
{产品价格}
);
}
既然你问过如何得到最好的回答
理想情况下,在发帖时,尝试创建一个其他人可以看到失败的问题案例。如果您尝试这样做(例如,使用CodeSandbox),但它在那里工作得很好,那么这就是一个清理您自己的本地环境的问题,直到您发现您的设置有什么独特之处,使代码对您而不是对其他人断开为止
理想情况下,如果您不能在一个页面复制(沙箱)中创建它,因为它与您的项目结构有关,那么可以通过在github上公开共享实际项目结构及其代码和配置来创建可运行的复制,这样人们就可以通过检出并构建/运行它来重新创建您的问题。这样,他们很快就能找到你的项目的与众不同之处
通常,创建复制的过程无论如何都会帮助您解决问题-例如,您从一个香草创建react应用程序typescript框架开始填充一个空白的github repo,然后您的问题案例突然在那里开始工作-现在您有了一个基础,可以通过将项目的特殊功能添加到只需重新编写,直到代码中断。您可以共享您的代码吗。如果不能够进行调查(例如,您的useState导入来自何处,它在何处被调用),很难想象其他代码可能会导致此错误。添加类型永远不会改变typescript传输的javascript代码,它只会改变编译器是否允许它无误运行。@cefn虽然我是一个长期的潜伏者,但这是第一次真正发布,所以我不能完全确定正确的方法。我将其作为代码片段添加,但如果效果更好,我可以做截图。我也没有包含任何配置文件,但是我在package.json中包含了React 17.0.2,所以我猜这就是导入的来源。谢谢你看!更奇怪的是,正如您所说,useState的第一行实现了您所想的,因为它应该返回一个数组,第一行包含一个值,第二行包含一个setter,而不是一个值。我开始怀疑您的环境是否设置了一些JSX配置,这意味着它根本没有将
解释为一个typescript泛型,而是一些其他的东西,比如HTML元素或其他东西。它显然是特定于您的环境或配置的。我将组合一个CodeSandbox,这可能是一个很好的方法,可以让您了解世界其他地方的情况。当您使用console.log(useState({}))
时,它会打印出什么@cefn不仅仅是
,它还有更多的泛型类型,如
和
,但JSX配置似乎是一个可能的罪魁祸首,因为我不得不从几个不同的教程中拼凑起来。啊!谢谢你的例子和关于发表好文章的信息。我还不知道有很多好的代码共享工具,所以我将尝试了解更多关于CodeSandbox的信息,并看看如何创建一个
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>
);
}