首页 > 解决方案 > 'map' 在 Redux 和 React 中未定义

问题描述

在未定义“地图”的情况下出现奇怪的错误。我不确定我的函数是否在错误的时间触发,这会导致没有接收到数据。

我正在将 Redux 添加到我的简单小应用程序中,该应用程序只是从 API 中提取数据并显示它。这是一堆英雄的列表。就像我之前说的,我认为错误来自 ansyc API 调用和 Redux 触发的不同时间。但话又说回来,我是一个新手,所以非常感谢任何帮助。

import React, {useEffect} from 'react'
import { connect } from 'react-redux'
import { fetchHeroes } from '../actions/heroesActions'
import { Hero } from '../components/Hero'

const HeroesPage = ({ dispatch, loading, heroes, hasErrors }) => {
    useEffect(() => {
        dispatch(fetchHeroes())
    }, [dispatch])

    const renderHeroes = () => {
        if (loading) return <p>Loading posts...</p>
        if (hasErrors) return <p>Unable to display posts.</p>
        return heroes.map(hero => <Hero key={hero.id} hero={hero} />)
    }

    return (
        <section>
            <h1>Heroes</h1>
            {renderHeroes()}
        </section>
    )
}

// Map Redux state to React component props
const mapStateToProps = state => ({
    loading: state.heroes.loading,
    heroes: state.heroes.heroes,
    hasErrors: state.heroes.hasErrors,
})

export default connect(mapStateToProps)(HeroesPage)
export const GET_HEROES = 'GET HEROES'
export const GET_HEROES_SUCCESS = 'GET_HEROES_SUCCESS'
export const GET_HEROES_FAILURE = 'GET_HEROES_FAILURE'


export const getHeroes = () => ({
  type: GET_HEROES,
})

export const getHeroesSuccess = heroes => ({
  type: GET_HEROES_SUCCESS,
  payload: heroes,
})

export const getHeroesFailure = () => ({
  type: GET_HEROES_FAILURE,
})


export function fetchHeroes() {
  return async dispatch => {
    dispatch(getHeroes())

    try {
      const response = await fetch('https://api.opendota.com/api/heroStats')
      console.log(response)
      const data = await response.json()

      dispatch(getHeroesSuccess(data))
    } catch (error) {
      dispatch(getHeroesFailure())
    }
  }
}

我创建商店的 index.js

// External imports
import React from 'react'
import { render } from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension'


// Local imports
import App from './App'
import rootReducer from './reducers'


const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))

render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
)

标签: javascriptreactjsredux

解决方案


import React, {useEffect} from 'react'
import { useSelector } from 'react-redux'
import { fetchHeroes } from '../actions/heroesActions'
import { Hero } from '../components/Hero'

const HeroesPage = () => {
    const data = useSelector(state => state.heroes);
    useEffect(() => {
        fetchHeroes();
    }, [])

    const renderHeroes = () => {
        if (data.loading) return <p>Loading posts...</p>
        if (data.hasErrors) return <p>Unable to display posts.</p>
        return data.heroes.map(hero => <Hero key={hero.id} hero={hero} />)
    }

    return (
        <section>
            <h1>Heroes</h1>
            {renderHeroes()}
        </section>
    )
}

export default HeroesPage

动作文件

// import store from your createStore file and access dispatch from it
dispatch = store.dispatch
export const GET_HEROES = 'GET HEROES'
export const GET_HEROES_SUCCESS = 'GET_HEROES_SUCCESS'
export const GET_HEROES_FAILURE = 'GET_HEROES_FAILURE'


export const getHeroes = () => ({
  type: GET_HEROES,
})

export const getHeroesSuccess = heroes => ({
  type: GET_HEROES_SUCCESS,
  payload: heroes,
})

export const getHeroesFailure = () => ({
  type: GET_HEROES_FAILURE,
})


export const fetchHeroes = () => {
  dispatch(getHeroes())

  try {
    const response = await fetch('https://api.opendota.com/api/heroStats')
    console.log(response)
    const data = await response.json()

    dispatch(getHeroesSuccess(data))
  } catch (error) {
    dispatch(getHeroesFailure())
  }
}

减速器文件

import * as actions from '../actions/heroesActions'
export const initialState = {
    heroes: [],
    loading: false,
    hasErrors: false,
}

export default function heroesReducer(state = initialState, action) {
    switch (action.type) {
        case actions.GET_HEROES:
            return { ...state, loading: true }
        case actions.GET_HEROES_SUCCESS:
            return { heroes: action.payload, loading: false, hasErrors: false }
        case actions.GET_HEROES_FAILURE:
            return { ...state, loading: false, hasErrors: true }
        default:
            return state
    }
}

推荐阅读