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

React分页组件重构:useEffect读取propTypes属性报错求助

React Hooks: TypeError when accessing propTypes/defaultProps in useEffect during class-to-function refactor

I see the exact issue here—you're hitting a common pitfall when transitioning from class components to function components with React Hooks. Let's break down what's going wrong and fix it step by step.

The Root Cause

Your error TypeError: Cannot read property 'items' of undefined comes from a critical mix-up: you're trying to access propTypes.items and propTypes.initialPage inside your useEffect hooks. The propTypes object is only for type validation—it doesn't hold the actual prop values being passed to your component. You need to pull these values from the props parameter instead.

On top of that, your second useEffect has invalid syntax: the first argument to useEffect is a function that doesn't receive prevProps as a parameter. To compare previous prop values, you'll need to use the useRef hook to track them.

Fixed Code Example

Here's how to adjust your code to resolve these issues:

import PropTypes from 'prop-types';
import { useState, useEffect, useRef } from 'react';

const propTypes = {
  items: PropTypes.array.isRequired,
  onChangePage: PropTypes.func.isRequired,
  initialPage: PropTypes.number,
  pageSize: PropTypes.number,
};

const defaultProps = {
  initialPage: 1,
  pageSize: 5,
};

function Pagination(props) {
  // Destructure props with fallback to default values for clarity
  const { items, initialPage = defaultProps.initialPage, pageSize = defaultProps.pageSize, onChangePage } = props;
  const [pager, setPager] = useState({});
  const prevItemsRef = useRef();

  // Initialize pagination on component mount (or when items/initialPage change)
  useEffect(() => {
    if (items && items.length) {
      setPage(initialPage);
    }
  }, [items, initialPage]); // Add dependencies to trigger effect when values change

  // Reset page when the items array updates
  useEffect(() => {
    // Compare current items with the stored previous version
    if (prevItemsRef.current && JSON.stringify(items) !== JSON.stringify(prevItemsRef.current)) {
      setPage(initialPage);
    }
    // Update ref to track the latest items for next render
    prevItemsRef.current = items;
  }, [items, initialPage]);

  // Define your setPage function (assuming this was missing from your snippet)
  const setPage = (pageNumber) => {
    const totalPages = Math.ceil(items.length / pageSize);
    // Update pager state with your pagination logic
    setPager({
      currentPage: pageNumber,
      totalPages,
      // Add other pager properties as needed
    });
    onChangePage(pageNumber);
  };

  return (
    // Your pagination JSX markup goes here
    <div className="pagination">
      {/* Example controls */}
      <button onClick={() => setPage(pager.currentPage - 1)} disabled={pager.currentPage === 1}>
        Previous
      </button>
      <span>Page {pager.currentPage} of {pager.totalPages}</span>
      <button onClick={() => setPage(pager.currentPage + 1)} disabled={pager.currentPage === pager.totalPages}>
        Next
      </button>
    </div>
  );
}

Pagination.propTypes = propTypes;
Pagination.defaultProps = defaultProps;

export default Pagination;

Key Fixes Explained

  1. Access props correctly: Replace propTypes.items with props.items (or use destructuring for cleaner code). The propTypes object is never meant to hold actual prop values—it's just for validation.
  2. Fix useEffect syntax: Use useRef to track the previous items prop, since useEffect doesn't pass prevProps directly. We update the ref after each render to keep a record of the prior state.
  3. Add proper dependencies: Both useEffect hooks include their dependencies (items, initialPage) so they trigger correctly when these values change (this also avoids React's dependency warnings).
  4. Optional: Destructure with defaults: Instead of relying solely on defaultProps, setting default values directly in the function parameter destructuring makes the code more readable (though defaultProps still works for function components if you prefer that approach).

Let me know if you hit any other snags while wrapping up the refactor!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 17:17:41