Типскрипт useState React Hook Ошибка деструктуризации (массив не возвращается?)

Я впервые занимаюсь простым приложением React и хочу настроить простой MVC для подключения к бэкэнду ASP.NET, и все это делается в Visual Studio 2019 (что вызвало некоторые проблемы с React). Однако теперь, когда я пытаюсь реализовать модели, я обнаружил, что все предложения по строгой типизации хука useState у меня не работают.

Согласно нескольким руководствам, таким как этот или this, это должно быть так же просто, как добавить тип в скобках, например const [state, setState] = useState<Type>({}), поскольку он имеет общую реализацию. К сожалению, для меня это вызывает ошибку Uncaught TypeError: недопустимая попытка деструктуризации не повторяемого экземпляра.

Этот поток здесь предложил переключиться с array в объект, изменив [] на {}, однако это просто сделало два параметра, которые я передал, неопределенными, поэтому у меня не было состояния или способа обновить указанное состояние.

Я пошел по пути чтения, пока не получил краткое представление о деструктуризации массива, поэтому я понимаю, что идея состоит в том, чтобы передать массив с двумя константами, которым будут назначены элементы массива, возвращаемые хуком 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;

Модель продукта -

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

person util42    schedule 04.04.2021    source источник
comment
Вы можете поделиться своим кодом. Трудно представить, что другой код мог сделать, чтобы внести свой вклад в эту ошибку, не имея возможности исследовать, например, откуда берется ваш импорт useState, где он вызывается. Добавление типов никогда не должно фактически изменять код javascript, который транслирует машинописный текст, он просто меняет, разрешит ли компилятор это без ошибок.   -  person cefn    schedule 04.04.2021
comment
@cefn Хотя я долгое время скрывался, это первый раз, когда я публикую, поэтому я не совсем уверен, как правильно это делать. Я добавил его как фрагмент кода, но я могу делать скриншоты, если это работает лучше. Я также не включил ни один из моих файлов конфигурации, но у меня есть React 17.0.2 в package.json, поэтому я предполагаю, что это то, из чего захватывается импорт. Спасибо, что заглянули!   -  person util42    schedule 05.04.2021
comment
Еще более странно то, что, как вы говорите, первая строка с useState делает то, что, по вашему мнению, предназначено, поскольку она должна возвращать массив, содержащий сначала значение, а затем установщик, а не значение вообще. Я начинаю задаваться вопросом, настроена ли ваша среда с некоторой конфигурацией JSX, что означает, что она вообще не интерпретирует <Product> как Generic машинописного текста, а что-то еще, например, элемент HTML или что-то в этом роде. Это определенно кажется специфичным для вашей среды или конфигурации. Я собираюсь собрать CodeSandbox, который может быть для вас хорошим способом понять, что верно для остального мира.   -  person cefn    schedule 05.04.2021
comment
Что он распечатывает, когда вы используете console.log(useState<Product>({}));   -  person Evan Trimboli    schedule 05.04.2021
comment
@cefn Дело не только в <Product>, но и в более общих типах, таких как <Number> и <Boolean>, но конфигурация JSX действительно кажется вероятным виновником, поскольку мне приходилось собирать ее из нескольких разных руководств.   -  person util42    schedule 05.04.2021
comment
@EvanTrimboli Он просто выводит false. Ни объект, ни массив не возвращаются. Однако console.log(useState(5)) возвращает массив, содержащий переменную состояния 5 и функцию для установки этого состояния.   -  person util42    schedule 05.04.2021


Ответы (1)


Вот 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, чтобы люди могли воссоздать ваш проблема, проверив его и собрав / запустив. Таким образом они скоро смогут отследить, что отличает ваш проект.

Часто этот процесс создания репродукции в любом случае поможет вам разобраться в проблеме - например, вы начинаете с ванильного скелета машинописного текста приложения create-response-app из https://create-react-app.dev/docs/adding-typescript/ для заполнения пустого репозитория github, и ваш проблемный случай внезапно начинает работать там - теперь у вас есть основа для разделения вашей проблемы пополам, добавив специальные функции вашего проекта в простое воспроизведение пока не сломается.

person cefn    schedule 05.04.2021
comment
Ах! Спасибо за пример и за информацию о создании хороших постов. Я до сих пор не знаю о многих инструментах для хорошего совместного использования кода, поэтому я постараюсь узнать больше о CodeSandbox и взглянуть на создание общедоступного репозитория github, чтобы я мог медленно воссоздавать свой проект, пока эта функциональность не сломается. , а затем поделитесь им, если я не могу понять, где я ошибся в конфигурации. - person util42; 05.04.2021