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

React项目切换分类后排序丢失且筛选无法自动触发问题求助

问题描述

我正在开发一个视频数据库应用,支持按分类筛选、按评分排序。切换筛选选项时功能正常,但切换视频分类后,排序不会自动触发,且排序状态会丢失。我已添加useEffect,但不清楚问题原因及调整方向,附上相关代码,请求帮助实现切换分类时保留排序状态。

更新内容:相关代码

HomePage组件

import * as _ from "lodash";
import { useEffect, useState } from "react";

import { getAllPrograms } from "../../helpers/getData";
import { TVProgram } from "../../models/models";
import Filters from "../Filters/Filters";
import ProgramsList from "../ProgramsList/ProgramsList";
import Sorting from "../Sorting/Sorting";
import "./HomePage.scss";

const HomePage = () => {
  const [programs, setPrograms] = useState<Array<TVProgram>>([]);
  const [category, setCategory] = useState<string>("movie,series");
  const [sortedPrograms, setSortedPrograms] = useState<TVProgram[]>(programs);

  const getPrograms = async (category: string) => {
    const programs = await getAllPrograms(category);
    setPrograms(programs);
  };

  useEffect(() => {
    getPrograms(category);
  }, [category]);

  const updateCategory = (categoryName: string): void => {
    setCategory(categoryName);
    console.log("catName", categoryName);
  };

  const updatePrograms = (sortedPrograms: TVProgram[]): void => {
    setSortedPrograms(sortedPrograms);
    console.log("sortedPrograms", sortedPrograms);
  };

  return (
    <div className="container">
      <div>
        <Filters
          updateCategory={updateCategory}
          currentCategory={category}
        ></Filters>
        <Sorting programs={programs} setPrograms={updatePrograms}></Sorting>
      </div>
      <ProgramsList programs={sortedPrograms}></ProgramsList>
    </div>
  );
};

export default HomePage;

Sorting组件

import _ from "lodash";
import { ChangeEvent, useEffect, useState } from "react";
import { sortProgramsByOrder } from "../../helpers/helpers";
import { TVProgram } from "../../models/models";
import "./Sorting.scss";

interface SortingListProps {
  programs: TVProgram[];
  setPrograms: (programs: TVProgram[]) => void;
}

const Sorting = ({ programs, setPrograms }: SortingListProps) => {
  const OPTIONS = ["imdb rating descending", "imdb rating ascending"];
  const [selectedOption, setSelectedOption] = useState<string>("");
  const [sortedPrograms, setSortedPrograms] = useState<TVProgram[]>([]);

  useEffect(() => {
    if (selectedOption === OPTIONS[0]) {
      setSortedPrograms(sortProgramsByOrder(programs, "desc"));
    } else if (selectedOption === OPTIONS[1]) {
      setSortedPrograms(sortProgramsByOrder(programs, "asc"));
    }
  }, [selectedOption, programs]);

  const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
    console.log();
    setSelectedOption(event.target.value);
    setPrograms(sortedPrograms);
  };

  return (
    <div>
      <select value={selectedOption} onChange={handleChange}>
        <option selected>Sortuj</option>
        {OPTIONS.map((option) => (
          <option
            key={option}
            value={option}
            selected={option === selectedOption}
          >
            {option}
          </option>
        ))}
      </select>
    </div>
  );
};

export default Sorting;

问题原因分析

  1. 排序状态本地化丢失:排序选择的状态selectedOption存储在Sorting组件内部,切换分类时HomePage重新获取数据并渲染,Sorting组件会被重新初始化,导致selectedOption重置为空,排序状态丢失。
  2. 新数据未自动应用排序:切换分类获取新的programs后,Sorting组件的useEffect虽依赖programs,但此时selectedOption为空,不会执行排序逻辑,因此新数据不会自动排序。
  3. 状态更新时机错误:handleChange中调用setPrograms(sortedPrograms)时,setSortedPrograms是异步操作,此时sortedPrograms还是旧值,无法正确传递最新排序结果。

解决方案及修改代码

1. 提升排序状态到父组件

将selectedOption从Sorting组件移到HomePage,确保切换分类时状态不会丢失,同时让父组件能在数据更新后自动应用排序规则。

修改后的HomePage组件

import * as _ from "lodash";
import { useEffect, useState } from "react";

import { getAllPrograms } from "../../helpers/getData";
import { TVProgram } from "../../models/models";
import Filters from "../Filters/Filters";
import ProgramsList from "../ProgramsList/ProgramsList";
import Sorting from "../Sorting/Sorting";
import { sortProgramsByOrder } from "../../helpers/helpers";
import "./HomePage.scss";

const HomePage = () => {
  const [programs, setPrograms] = useState<Array<TVProgram>>([]);
  const [category, setCategory] = useState<string>("movie,series");
  const [sortedPrograms, setSortedPrograms] = useState<TVProgram[]>([]);
  // 把排序状态提升到父组件
  const [sortOption, setSortOption] = useState<string>("");
  const SORT_OPTIONS = ["imdb rating descending", "imdb rating ascending"];

  const getPrograms = async (category: string) => {
    const programs = await getAllPrograms(category);
    setPrograms(programs);
  };

  // 当分类或排序选项变化时,重新执行排序
  useEffect(() => {
    let result = [...programs];
    if (sortOption === SORT_OPTIONS[0]) {
      result = sortProgramsByOrder(programs, "desc");
    } else if (sortOption === SORT_OPTIONS[1]) {
      result = sortProgramsByOrder(programs, "asc");
    }
    setSortedPrograms(result);
  }, [programs, sortOption]);

  useEffect(() => {
    getPrograms(category);
  }, [category]);

  const updateCategory = (categoryName: string): void => {
    setCategory(categoryName);
  };

  return (
    <div className="container">
      <div>
        <Filters
          updateCategory={updateCategory}
          currentCategory={category}
        ></Filters>
        <Sorting
          currentSortOption={sortOption}
          setSortOption={setSortOption}
        ></Sorting>
      </div>
      <ProgramsList programs={sortedPrograms}></ProgramsList>
    </div>
  );
};

export default HomePage;

修改后的Sorting组件

import { ChangeEvent } from "react";
import "./Sorting.scss";

interface SortingListProps {
  currentSortOption: string;
  setSortOption: (option: string) => void;
}

const Sorting = ({ currentSortOption, setSortOption }: SortingListProps) => {
  const OPTIONS = ["imdb rating descending", "imdb rating ascending"];

  const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
    setSortOption(event.target.value);
  };

  return (
    <div>
      <select value={currentSortOption} onChange={handleChange}>
        <option value="">Sortuj</option>
        {OPTIONS.map((option) => (
          <option
            key={option}
            value={option}
          >
            {option}
          </option>
        ))}
      </select>
    </div>
  );
};

export default Sorting;

修改说明

  • 状态提升:将sortOption移到HomePage,切换分类时状态不会被重置,保留用户的排序选择。
  • 统一排序逻辑:在HomePage中添加依赖programs和sortOption的useEffect,每当分类切换获取新数据,或用户修改排序选项时,自动执行排序并更新sortedPrograms。
  • 简化Sorting组件:Sorting仅负责展示下拉选项和传递排序选择,不再处理排序逻辑,职责更单一。
  • 修正默认选项:将默认的空选项value设为"",避免选中状态混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:35:20