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

React项目双export default解析错误及分页功能实现问题咨询

问题分析与解决方案

现有代码存在的核心问题

  • 重复默认导出错误:同一个JS模块只能有一个export default,你同时将ProductApp和App都设为默认导出,是直接触发运行报错的首要原因。
  • API地址拼写错误:使用的jsonplaceholder地址缺少.com后缀,正确地址为https://jsonplaceholder.typicode.com/posts,错误地址会直接导致请求失败。
  • 函数组件返回逻辑缺失:ProductApp只写了error状态的返回,正常加载、产品列表渲染的逻辑完全缺失,组件渲染时会抛出异常。
  • 路由规则冲突:/signin路径匹配了两个Route,Switch只会渲染第一个命中的路由,第二个LogOut相关的路由永远不会生效。
  • 分页功能完全缺失:没有定义分页参数、触发逻辑,请求时也没有携带分页参数,完全不满足适配动态新增产品的分页需求。
  • 加载状态未处理:请求产品数据过程中没有loading提示,用户容易误以为页面卡住。
  • 逻辑冗余:类组件中handleSignOut和handleLogout、handleSignIn和handleLogin功能完全重复,属于无用冗余代码。
  • 依赖导入缺失:代码中用到的axios、react-router相关组件、各个页面组件都没有写导入语句,运行时会报未定义错误。

最优解决方案

1. 基础错误修复

  • 拆分组件:将ProductApp单独存放在/src/components/ProductApp.jsx文件中,不要和根App组件放在同一个文件,解决重复默认导出的问题。
  • 修正API地址:把请求地址替换为正确的接口地址,对接自有产品接口时换成自己的后端分页接口即可。
  • 补全导入语句:在对应文件顶部导入所有用到的依赖。

2. 分页功能实现

采用偏移分页方案适配产品动态新增场景,实现代码如下:

// src/components/ProductApp.jsx
import React, { useState, useEffect } from 'react';

// 可自定义每页展示的产品数量
const PAGE_SIZE = 10;
const BASE_URL = 'https://jsonplaceholder.typicode.com/posts';

export default function ProductApp() {
  const [products, setProducts] = useState([]);
  const [error, setError] = useState('');
  const [currentPage, setCurrentPage] = useState(1);
  const [isLoading, setIsLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);

  useEffect(() => {
    const fetchProducts = async () => {
      setIsLoading(true);
      try {
        // 向后端传递分页参数,_page为当前页码、_limit为每页条数,可根据后端要求调整参数名
        const res = await fetch(`${BASE_URL}?_page=${currentPage}&_limit=${PAGE_SIZE}`);
        if (!res.ok) throw new Error('数据请求失败');
        const data = await res.json();
        // 从响应头获取总数据量,判断是否还有下一页
        const totalCount = Number(res.headers.get('X-Total-Count'));
        setProducts(prev => currentPage === 1 ? data : [...prev, ...data]);
        setHasMore(currentPage * PAGE_SIZE < totalCount);
      } catch (err) {
        setError(err.message);
      } finally {
        setIsLoading(false);
      }
    };

    fetchProducts();
  }, [currentPage]);

  if (error) return <h1>{error}</h1>;

  return (
    <div className="product-container">
      <h2>产品列表</h2>
      <div className="product-list">
        {products.map(product => (
          <div key={product.id} className="product-item">
            <h3>{product.title}</h3>
            <p>{product.body}</p>
          </div>
        ))}
      </div>
      {isLoading && <p>加载中...</p>}
      <div className="pagination">
        <button 
          onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
          disabled={currentPage === 1 || isLoading}
        >
          上一页
        </button>
        <span>当前第 {currentPage} 页</span>
        <button
          onClick={() => setCurrentPage(prev => prev + 1)}
          disabled={!hasMore || isLoading}
        >
          下一页
        </button>
      </div>
    </div>
  );
}

3. 根App组件修复

调整路由规则,删除冗余逻辑,修复后代码如下:

// src/App.jsx
import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import axios from 'axios';
// 按自己的文件路径导入对应的页面组件
import Home from './components/Home';
import Main from './components/Main';
import Products from './components/Products';
import ContactUs from './components/ContactUs';
import SignUp from './components/SignUp';
import Login from './components/Login';
import LogOut from './components/LogOut';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loggedInStatus: "NOT_LOGGED_IN",
      user: {}
    };
    this.handleLogin = this.handleLogin.bind(this);
    this.handleUnsuccesfulLogin = this.handleUnsuccesfulLogin.bind(this);
    this.handleLogout = this.handleLogout.bind(this);
  }

  handleLogin(data) {
    this.setState({
      loggedInStatus: "LOGGED_IN",
      user: data.user
    });
  }
  
  handleUnsuccesfulLogin() {
    this.setState ({
      loggedInStatus: "NOT_LOGGED_IN"
    });
  }

  handleLogout() {
    this.setState({
      loggedInStatus: "NOT_LOGGED_IN",
      user: {}
    });
  }
  
  checkLoginStatus() {
    return axios
      .get("http://localhost:3001/logged_in", 
        { withCredentials: true })
          .then(response => {
            const loggedIn = response.data.logged_in;
            const loggedInStatus = this.state.loggedInStatus;

            if (loggedIn && loggedInStatus === "NOT_LOGGED_IN") {
              this.setState ({
                loggedInStatus: "LOGGED_IN"
              });
            } else if (!loggedIn && loggedInStatus === "LOGGED_IN") {
              this.setState({
                loggedInStatus: "NOT_LOGGED_IN"
              });
            }
            return loggedIn;
          })
          .catch(error => {
            console.log("Error", error);
          });
  }

  componentDidMount() {
    this.checkLoginStatus();
  }

  render() {
    return (
      <Router>
          <Home />
        <Switch>
          <Route
                exact 
                path={'/'}
                render={props => (
                  <Main
                    {...props}
                    handleLogin={this.handleLogin}
                    handleLogout={this.handleLogout}
                    loggedInStatus={this.state.loggedInStatus}
                  />
                )}
                />
          <Route path='/products' component={Products}/>
          <Route path='/contactus' component={ContactUs}/>
          <Route path='/signup' component={SignUp}/>
          <Route
                exact
                path={"/signin"}
                render={props => (
                  this.state.loggedInStatus === "LOGGED_IN" ? 
                  <LogOut {...props} handleLogout={this.handleLogout} /> :
                  <Login {...props} handleLogin={this.handleLogin} handleUnsuccesfulLogin={this.handleUnsuccesfulLogin} />
                )}
          />
          {/* <Route path='/profile' component={Profile}/> */}
        </Switch>
      </Router>   
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:57:04