与useContext反应打字稿地图不起作用

时间:2020-05-13 21:01:17

标签: javascript reactjs typescript fetch react-hooks

我尝试使用react typescript和useContext从tvmaze api中获取一些数据,我可以显示数据,但useContext不会随返回值更新,因此当我使用map函数时,什么也没有显示任何建议?

import React , { Fragment, useEffect, useContext, useState } from 'react'
import axios from 'axios'
import Store from '../Store/Store'
import "core-js/stable";
import "regenerator-runtime/runtime";

export default function App() {

  const {state, dispatch} = useContext(Store)

  useEffect(() => {
    state.episodes.length === 0 && fetchDataAction()
  })

  const fetchDataAction = async () => {
    const URL = 'http://api.tvmaze.com/singlesearch/shows?q=rick-&-morty&embed=episodes'
    const data = await fetch(URL);
    const dataJSON = await data.json();
    console.log(dataJSON._embedded.episodes);
    return dispatch({
      type: "FETCH-DATA",
      payload: dataJSON._embedded.episodes,
    })
  }

  return (
    <Fragment>
      {console.log(state)}
      <h1>Rick and Morty</h1>
      <p>Pick your favorite episode!!!</p>
      <section>
        {state.episodes.map((episode: any) => {
          return (
            <section key={episode.id}>
              <img src={episode.image.medium} alt={`Rick and Morty ${episode.name}`} />
              <section>
                Season: {episode.season} Number: {episode.number}
              </section>
            </section>
          )
        })}
      </section>
    </Fragment>
  )
}

我没有使用redux,但是我使用的是babel + webpack,我对这一切真的很陌生,所以我的Store.tsx文件在这里有点迷路了,

 import React from 'react'

    interface IState {
      episodes: [],
      favorites: []
    }

    interface IAction {
      type: string,
      payload: any
    }

    const initialState:IState = {
      episodes: [],
      favorites: []
    };


    const Store = React.createContext<IState | any>(initialState)

    function reducer(state: IState, action: IAction): IState {
      switch (action.type) {
        case 'FETCH_DATA':
          return { ...state, episodes: action.payload}
        default:
          return state
      }
    }

    export function StoreProvider(props: any): JSX.Element {
      const [state, dispatch] = React.useReducer(reducer, initialState)
      return <Store.Provider value={{state, dispatch}}>{props.children}</Store.Provider>
    };

    export default Store;

1 个答案:

答案 0 :(得分:0)

您有错字。您正在调度类型:“ FETCH-DATA”,并且您的Swich语句正在检查大小写“ FETCH_DATA”。

为避免将来出现此问题,通常的做法是创建一个单独的文件,在该文件中您将声明操作,在这种情况下为“ FETCH_CASE”。您可以按字面意思const FETCH_ACTIONS = "FETCH_ACTIONS"

然后在减速器和调度器所在的文件中,导入操作以确保它们引用的是同一事物。

  1. redux和webpack / babel的用途不同-redux用于商店管理,类似于useContext。 webpack和babel或多或少会编译您的代码。

  2. 如果您不使用axios,则无需导入它,而您使用fetch API的目的与使用axios的目的相同。

  3. 您必须先声明fetchDataAction,然后才能在useEffect中调用它。换句话说,useEffect应该在函数下方。