redux 如何在Typescript中使用/创建数组类型

4dc9hkyq  于 2022-12-13  发布在  TypeScript
关注(0)|答案(2)|浏览(153)

我有一个react项目,我正在创建一个商店。代码如下:

import React, { useReducer, useEffect } from 'react';
import { v4 as uuid } from 'uuid';

import { Movie, MoviesAction } from 'types';
import { getMovies } from 'api/movies';

interface MoviesState {
  movies: Movie[]
  initialized: boolean
}

export function useMoviesCollection(): [MoviesState, React.Dispatch<MoviesAction>] {
  // TODO: Implement all action processing

  const movieReducer = (state: MoviesState, action: MoviesAction): MoviesState => {
    switch (action.type) {
      case 'fetch':
        
          console.log('ss', state)
          // return {...state}
          return { ...state, movies: action.payload };
         
        // return { ...state };

      case 'add':
        return { ...state };

      case 'delete':
        return { ...state };

      case 'rate':
        return { ...state };

      default:
        return state
    }
  };

  const [state, dispatch] = useReducer(movieReducer, {
    movies: [],
    initialized: false,
  });

  useEffect( () => {
    // TODO: Call fetch action
    
     getMovies().then((d)=>{
      console.log('g', d)
         dispatch({
          type: 'fetch',
          payload: {
              data: d
          }
      })
     })
  }, []);

  return [state, dispatch];
}

在我的useEffect钩子中,我试图调用一个API,然后使用Data/result将其作为动作的有效负载传递到分派内部。尽管API调用返回的是电影数组的类型Movie[],但当我将其设置为inside the state时,我得到了以下错误消息:

Type '{ data: Movie[]; }' is missing the following properties from type 'Movie[]': length, pop, push, concat, and 28 more.

getMovies API调用的实现如下:

import { Movie } from "types"

export const getMovies = async (): Promise<Movie[]> => {
    return require('../data/movies.json')
}

MovieAction和Movie的类型/接口声明为:

export interface Movie {
    id: string,
    title: string,
    subtitle: string,
    description: string,
    imageUrl: string,
    ratings: number[]
}

export interface MovieFetchAction {
    type: 'fetch',
    payload: {
        data: Movie[]
    }
}

有谁能告诉我我在这里错了什么吗?我觉得我通过的是正确的类型。

epggiuax

epggiuax1#

你会踢自己:
你在写

dispatch({
          type: 'fetch',
          payload: {
              data: d
          }
      })

而你应该写

dispatch({
          type: 'fetch',
          payload: d
      })

顺便说一句,我会把整件事改写成

useEffect( () => {
    // TODO: Call fetch action
    const doFetch = async() => {
     const payload = await getMovies();
     console.log('payload', payload)
     dispatch({
          type: 'fetch',
          payload
     });
    };

    doFetch();
  }, []);

哪一个(imo)更具可读性。
这里你应该注意到的一件事是Typescript给你带来的巨大优势。如果你在Javascript中犯了同样的错误,你将不会发现它,直到商店的某个消费者在未来的某个时候失败。

rsl1atfo

rsl1atfo2#

错误消息指出了明显的错误。您传递的payload类型为{data:Movie[]},而在Moviestate中,电影的类型为“Movie[]”。
您需要在return内链接呼叫data属性,以传回正确的型别。
用途:

return { ...state, movies: action.payload.data };

相关问题