Реагируйте на пользовательский хук с контекстом и типографским сценарием: свойство 'map' не существует для типа 'Option' - PullRequest
2 голосов
/ 05 февраля 2020

Я работаю над приложением React, которое содержит Custom Hook, доступный через Context. Приложение использует Typescript и определяет пользовательские типы, такие как Option, который представляет собой объект, представляющий состояние элемента Radio или флажка.

В общих чертах это шаги, которым следует код:

  • Создает контекст в верхней части дерева компонентов, который содержит пользовательский хук состояния
  • Пользовательский хук содержит пользовательский тип Typescript (опция)
  • Вниз по дереву компонент читает пользовательское состояние ловушка для визуализации Rad ios или флажки

Сначала он определяет пользовательский крючок с контекстом, чтобы сделать его доступным для остальных компонентов. Он также включает в себя пользовательский тип Option:

import React from "react";

// Custom Option type
export type Option = {
    name: string;
    enabled: boolean;
    checked: boolean;
};

const FiltersContext = React.createContext<Option[] | null>(null);

function useFilters() {
    const context = React.useContext(FiltersContext);
    if (!context) {
        throw new Error(`useFilters must be used within a FiltersProvider`);
    }
    const [filters, setFilters] = context;

    return {
        filters,
        setFilters
    };
}

function FiltersProvider(props: any) {
    // Prepare default options array
    const options: Option[] = [
        {
            name: "Option 1",
            enabled: true,
            checked: true
        },
        {
            name: "Option 2",
            enabled: true,
            checked: false
        }
    ];

    // Assigns default options
    const [filters, setFilters] = React.useState<Option[]>(options);
    const value = React.useMemo(() => [filters, setFilters], [filters]);

    return <FiltersContext.Provider value={value} {...props} />;
}

export { FiltersProvider, useFilters };

Позже и вниз по дереву у меня есть компонент, который читает состояние этого пользовательского хука. Проблема возникает здесь:

import * as React from "react";
import { Option, useFilters } from "../../context/use-filters";

const Options: React.FC = () => {
    const { filters } = useFilters();

    return (
        <Wrapper>
            {filters.map((option: Option, key: number) => (
                <OptionWrapper key={key}>
                    <RadioButton defaultChecked={false} name={option.name} disabled={false} onClick={() => {}} />
                    <Label>{option.name}</Label>
                </OptionWrapper>
            ))}
        </Wrapper>
    );
};

export default Options;

Код получает filters из useFilters, а затем map через них для создания RadioButton компонентов. Typescript жалуется, говоря:

Property 'map' does not exist on type 'Option'

Итак, насколько я понимаю, filters определяется как тип Option, а не как массив параметров.

Если I l oop до filters до return, опции появляются на консоли, но Typescript по-прежнему жалуется на эту ошибку:

filters.map((option: Option) => console.log(option.name));

Я уверен, что неправильно понимаю что-то очень важное, поэтому прошу прощения заранее , но если бы вы могли пролить на него немного света, я был бы очень благодарен!

Еще раз спасибо!

1 Ответ

1 голос
/ 06 февраля 2020

Ваш тип контекста неправильный, он должен выглядеть примерно так:

const FiltersContext = React.createContext<[Option[], Dispatch<SetStateAction<Option[]>>] | null>(null);

Ваш контекст будет означать, что вы возвращаете только фильтры в качестве значения контекста, но вы также возвращаете функцию setFilters, поэтому вам нужно учитывать это тоже. Печатается для setFilter:

import { Dispatch, SetStateAction } from 'react';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...