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

如何在React中为setState添加类型定义?解决Context中setPageNumber类型不匹配报错

解决React Context中setState的类型定义问题

嘿,你的问题很典型——就是Context的类型定义和实际传递的value不匹配导致的,咱们一步步来修复:

1. 修正MoviesContextData类型定义

你当前的MoviesContextData只包含了movies和pageNumber,但你在Provider的value里还传了setPageNumber,所以必须把这个属性添加到类型中,并且要正确定义它的类型:

export type MoviesContextData = { 
  movies: MovieData[]; 
  pageNumber: number;
  // 这里添加setPageNumber的类型,对应number类型状态的dispatch函数
  setPageNumber: React.Dispatch<React.SetStateAction<number>>;
}

这里React.Dispatch<React.SetStateAction<number>>是React内置的类型,专门用来描述useState返回的状态更新函数,SetStateAction<number>表示这个函数可以接收一个number值,或者一个返回number的回调函数。

2. (可选但推荐)显式指定useState的类型

虽然TypeScript能自动推断pageNumber的类型,但显式指定会让代码更清晰,避免潜在的类型问题:

const [pageNumber, setPageNumber] = useState<number>(1)

3. 修复useEffect的依赖数组

你当前的useEffect依赖是空数组,这意味着只会在组件挂载时请求一次数据,当pageNumber变化时不会重新请求。记得把pageNumber加入依赖数组:

useEffect(() => {
  axios.get(`${POPULAR_BASE_URL}&page=${pageNumber}`)
    .then(response => {
      setMovies(response.data.results)
    })
}, [pageNumber]) // 这里添加pageNumber作为依赖

完整修正后的代码

export type MoviesContextData = { 
  movies: MovieData[]; 
  pageNumber: number;
  setPageNumber: React.Dispatch<React.SetStateAction<number>>;
}
export type MovieData = { 
  id: number; 
  backdrop_path: string; 
  poster_path: string; 
  title: string; 
  release_date: string; 
  vote_average: number; 
}

import { useContext, createContext, useEffect, useState } from "react"
import { MoviesProviderProps } from "../interfaces/props"
import { MovieData, MoviesContextData } from "../interfaces/types"
import axios from "axios"
import { POPULAR_BASE_URL } from "../services/api"

const MoviesContext = createContext<MoviesContextData>({} as MoviesContextData)

export const MoviesProvider = ({ children }: MoviesProviderProps) => {
  const [movies, setMovies] = useState<MovieData[]>([])
  const [pageNumber, setPageNumber] = useState<number>(1)

  useEffect(() => {
    axios.get(`${POPULAR_BASE_URL}&page=${pageNumber}`)
      .then(response => {
        setMovies(response.data.results)
      })
  }, [pageNumber])

  return (
    <MoviesContext.Provider value={{ movies, pageNumber, setPageNumber }}>
      {children}
    </MoviesContext.Provider>
  )
}

export const useMovies = () => {
  const context = useContext(MoviesContext)
  return context
}

这样修改后,类型不匹配的错误就会消失,同时代码的健壮性也提升了——页码变化时会自动重新请求对应页的电影数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 19:37:39