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

使用slice()触发TypeError,求Pokemon列表分页解决方案

问题修复方案

错误根源

你碰到的TypeError: Cannot read properties of null (reading 'slice'),是因为组件初始化时state.pokemon设为了null,而displayUsers的定义早于return中的条件渲染逻辑。第一次render时,代码会直接对null调用slice方法,触发报错——哪怕后面有this.state.pokemon ? ...的判断,也来不及阻止错误发生,因为代码执行顺序是先计算displayUsers再进入条件分支。

具体修复步骤

1. 修正初始state的pokemon值

把state里的pokemon: null改成pokemon: [],空数组可以安全调用slice和map方法,不会触发报错:

state = {
    url: "https://pokeapi.co/api/v2/pokemon?limit=100000&offset=0",
    pokemon: [], // 替换null为空数组
    pageNumber: 1,
    pokemonsPerPage: 16
};

2. 修复分页计算逻辑

当前pagesVisited = this.state.pageNumber * this.state.pokemonsPerPage会导致第一页从第17个元素开始(pageNumber=1时,1*16=16),正确的起始位置应该是(pageNumber-1)*pokemonsPerPage:

const pagesVisited = (this.state.pageNumber - 1) * this.state.pokemonsPerPage;

3. 优化条件渲染判断

空数组在JavaScript中属于truthy值,原来的this.state.pokemon ? ...会显示空的div.row,应该改成判断数组长度,确保无数据时显示加载提示:

{this.state.pokemon.length > 0 ? ( 
    <div className='row'>
        {displayUsers}
    </div>
) : (<h2>Loading Pokemon</h2>)} 

可选方案:添加空值保护(不修改初始state的情况)

如果坚持初始pokemon为null,可以在定义displayUsers时加一层空值判断:

const displayUsers = this.state.pokemon
    ? this.state.pokemon.slice(pagesVisited, pagesVisited + this.state.pokemonsPerPage)
        .map((pokemon) => {
            return (
                <PokemonCard 
                    key={pokemon.name} 
                    name={pokemon.name} 
                    url={pokemon.url} 
                /> 
            )
        })
    : []

修复后的完整代码

import React, { Component } from 'react'
import axios from 'axios'
import ReactPaginate from 'react-paginate';

import PokemonCard from './PokemonCard';


export default class PokemonList extends Component {
    state = {
        url: "https://pokeapi.co/api/v2/pokemon?limit=100000&offset=0",
        pokemon: [],
        pageNumber: 1,
        pokemonsPerPage: 16
    };

    async componentDidMount() {
        const res = await axios.get(this.state.url); 
        console.log(res.data['results']);
        this.setState({pokemon: res.data['results']}); 
    };

    render() {
        console.log(this.state.pokemon);

        const pagesVisited = (this.state.pageNumber - 1) * this.state.pokemonsPerPage;

        const displayUsers = this.state.pokemon
            .slice(pagesVisited, pagesVisited + this.state.pokemonsPerPage)
            .map((pokemon) => {
                return (
                    <PokemonCard 
                        key={pokemon.name} 
                        name={pokemon.name} 
                        url={pokemon.url} 
                    /> 
                )
            })
        return (
            <React.Fragment>
                {this.state.pokemon.length > 0 ? ( 
                    <div className='row'>
                        {displayUsers}
                    </div>
                ) : (<h2>Loading Pokemon</h2>)} 
            </React.Fragment>
        )
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:31:08