React, Typescript, Hooks - деструктурирование данных из ловушки, TS2339: свойство «data» не существует для типа - PullRequest
0 голосов
/ 17 апреля 2020

У меня проблема с деструктуризацией объекта данных Typescript из моего собственного хука, созданного в React.

export interface InitialState {
  pokemonListLoading: false;
  pokemonListLoadingFailed: false;
  data: [];
}

interface FetchPokemonList {
  type: typeof FETCH_POKEMON_LIST;
}

interface FetchPokemonListSuccess {
  type: typeof FETCH_POKEMON_LIST_SUCCESS;
  payload: PokemonList;
}

...

export type PokemonListActionTypes = FetchPokemonList | FetchPokemonListSuccess | FetchPokemonListError;

const dataFetchReducer = (state: InitialState, action: PokemonListActionTypes) => {
  switch (action.type) {
    case FETCH_POKEMON_LIST:
      return {
        ...state,
        pokemonListLoading: true,
        pokemonListLoadingFailed: false,
      };
    case FETCH_POKEMON_LIST_SUCCESS:
      return {
        ...state,
        pokemonListLoading: false,
        pokemonListLoadingFailed: false,
        data: action.payload,
      };
    case FETCH_POKEMON_LIST_ERROR:
      return {
        ...state,
        pokemonListLoading: false,
        pokemonListLoadingFailed: true,
      };
    default:
      throw new Error();
  }
};

export const fetchPokemonList = (initialUrl: string, initialData: []) => {
  const [url, setUrl] = useState(initialUrl);
  const [state, dispatch] = useReducer(dataFetchReducer, {
    pokemonListLoading: false,
    pokemonListLoadingFailed: false,
    data: initialData,
  });

  useEffect(() => {
    const fetchData = async () => {
      dispatch({ type: FETCH_POKEMON_LIST });
      try {
        const result = await axios(url);
        dispatch({ type: FETCH_POKEMON_LIST_SUCCESS, payload: result.data });
      } catch (error) {
        dispatch({ type: FETCH_POKEMON_LIST_ERROR });
      }
    };

    fetchData();
  }, [url]);

  return [state, setUrl];
};

и весь компонент

import React, { FunctionComponent } from 'react';
import { fetchPokemonList, InitialState } from '../../hooks/fetchPokemonList';

const PokemonList: FunctionComponent = () => {
  const [{
      data: { results: pokemonList },
      pokemonListLoading,
      pokemonListLoadingFailed,
    },
  ] = fetchPokemonList('https://pokeapi.co/api/v2/pokemon',[]);

  return (
    <div>
      PokemonList
      {pokemonListLoading ? (
        <div>Laoding...</div>
      ) : (
      pokemonList && pokemonList.map((pokemon: { name: string}) => (
          <div key={pokemon.name}>{pokemon.name}</div>
        ))
      )}
      {pokemonListLoadingFailed && <div>Error</div>}
    </div>
  )
}

export { PokemonList }

код ошибки, отображаемый Webstorm

TS2339: свойство 'data' не существует для типа '{pokemonListLoading: булева; pokemonListLoadingFailed: boolean; данные: []; } | {pokemonListLoading: boolean; pokemonListLoadingFailed: boolean; данные: PokemonList; } | Отправка ... >> '.

1 Ответ

0 голосов
/ 17 апреля 2020

Проблема находится в этой строке:

dispatch({ type: FETCH_POKEMON_LIST_SUCCESS, payload: result.data });

Где вы отправляете в качестве полезной нагрузки без использования ключа для вашего нового значения data.

Затем в разделе кода вы установка data с объектом полезной нагрузки, что приводит к ошибке, с которой вы сталкиваетесь:

case FETCH_POKEMON_LIST_SUCCESS:
  return {
    ...state,
    pokemonListLoading: false,
    pokemonListLoadingFailed: false,
    data: action.payload,
  };

Попробуйте передать свою полезную нагрузку следующим образом: payload: { data: result.data }. Затем установите data соответственно: data: action.payload.data

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...