You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+TypeScript+Redux电影项目报movieList.map is not a function错误如何解决

报错原因分析
  • 核心原因是你存在Redux的movies.data字段不是数组类型,所以调用map方法失败,具体由以下几个错误共同导致:
    1. 接口返回结构解析错误:你在types.ts中已经定义了Movies接口,说明后端返回的电影列表是包裹在results字段中的对象,但是你在action中直接将整个接口返回值断言为Results[]类型,将对象存入了原本应该是数组的data字段中
    2. 请求前未设置加载状态:初始状态loading为false,且你没有在发起请求前触发setLoading,接口请求未完成时就进入了列表渲染逻辑
    3. 重复请求风险:你在App组件顶层直接调用dispatch(getMovies()),每次组件渲染都会重新触发请求,可能导致返回结果时序混乱
    4. 渲染判断条件不严谨:仅判断movieList != null无法保证它是数组类型,哪怕data被存入了对象也会进入列表渲染分支
解决办法

1. 修正movieAction中的请求逻辑

首先在发起请求前设置加载状态,然后正确解析接口返回的results字段:
把你的getMovies方法改成如下:

export const getMovies = ():ThunkAction<void, RootState, null, MovieAction>=>{
    return async dispatch => {
      // 发起请求前先设为加载中
      dispatch(setLoading())
      try {
        const res = await fetch(`https://localhost:44325/popular`,{
            headers:{
                'ApiKey':`1808BX234TSY`,
            }
        });
        if (!res.ok) {
            const resData: MoviesError = await res.json();
            throw new Error(resData.message);
        }
        // 正确解析返回结构,取results字段
        const resData:Movies = await res.json();
        dispatch({
            type: GET_MOVIES,
            payload: resData.results
        });
      } catch (error) {
        if(error instanceof Error){
          dispatch({
              type: SET_ERROR,
              payload: error.message
          })
        }
      }
    }
}

2. 修正App组件的请求触发和渲染逻辑

用useEffect包裹请求触发逻辑避免重复请求,同时调整渲染判断条件,优先判断加载状态,再判断数组类型:
把App组件改成如下:

const App = ()=>{
  const dispatch = useDispatch();
  const movieList = useSelector((state: RootState)=>state.movies.data) || [];
  const loading = useSelector((state: RootState)=>state.movies.loading);
  const error = useSelector((state: RootState)=>state.movies.error);
  
  // 仅组件挂载时触发一次请求
  React.useEffect(() => {
    dispatch(getMovies())
  }, [dispatch])

  console.log(movieList);
  return(
    <div className="body">
      <Container fluid >
        {/* 优先判断加载状态 */}
        {loading ? (
          <SpinnerComponent />
        ) : error ? (
          <div className="text-danger">加载失败:{error}</div>
        ) : movieList.length > 0 ? (
          <Row className='row-cols-1 row-cols-md-4 g-3' >
            {movieList.map((movie, index)=>(
              <MovieCard movie = {movie} key={index} />
            ))}
          </Row>
        ) : (
          <div className="text-center">暂无电影数据</div>
        )}
      </Container>
    </div>
  )
}

内容的提问来源于stack exchange,提问作者Jacob Mutale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 05:06:03