如何在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
相关产品推荐
相关产品推荐

