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

React删除未使用的sortType状态后状态不更新问题及解决

React操作State删除未使用变量后状态停止更新问题

问题描述

在实现自行车数据按年份排序功能时,删除代码中全程未使用的sortType状态相关代码后,出现状态停止更新、无任何报错、UI不刷新的异常;保留sortType相关代码时功能可正常运行。

问题代码

import BikeCard from "../components/BikeCard";
import Layout from "../components/Layout";
import { getAllBikes } from "../lib/bikes";
import Head from "next/head";
import { useState } from "react";
import BikeGallery from "../components/BikeGallery";

export default function Home({ data }) {
    const allBikes = []; // 默认数据
    data.forEach((model) => model.bikes.forEach((bike) => allBikes.push(bike)));
    const [displayData, setDisplayData] = useState(allBikes);
    const [sortType, setSortType] = useState("make"); // 打算删除该行

    const SortByInputHandler = (e) => {
        setSortType(e.target.value); // 打算删除该行
        if (e.target.value === "year") {
            setDisplayData(sortByYear(allBikes)); // 按年份排序默认数据后存入State
        } else if (e.target.value === "make") {
            setDisplayData(allBikes);
        }
    };
    const sortByYear = (data) => {
        let arr = data;
        arr.sort((a, b) => {
            return b.year > a.year ? 1 : b.year < a.year ? -1 : 0;
        });
        return arr;
    };
    return (
        <Layout>
            <Head>
                <title>Ride 4 - Bikes</title>
            </Head>
            <div>
                <div>
                    <label>排序方式:</label>
                    <select onChange={SortByInputHandler}>
                        <option value="make">品牌</option>
                        <option value="year">年份</option>
                    </select>
                </div>
            </div>
            <BikeGallery displayData={displayData} />
        </Layout>
    );
}

export async function getStaticProps() {
    const data = getAllBikes();
    return {
        props: { data },
    };
}

根因分析

  1. JavaScript中Array.sort()是原地排序方法,原代码中let arr = data仅赋值了数组的引用,排序操作会直接修改原始的allBikes数组本身,没有生成新的数组。
  2. React更新State时会做浅比较,传入setDisplayData的还是原来的数组引用时,React会判定State没有变化,不会触发组件重渲染。
  3. 保留sortType相关代码时功能正常的原因:每次触发排序事件都会调用setSortType更新另一个State,只要有任意State更新就会触发组件重渲染,此时displayData虽然引用未变,但指向的原数组已经被原地修改,重渲染时会读取到最新值,所以看起来功能正常。删除sortType后没有其他State触发重渲染,displayData引用未被React识别为变化,就出现了状态不更新的表象。

解决方案

修改排序逻辑,创建原数组的副本再执行排序操作,保证返回的是全新的数组引用:
将sortByYear函数中的let arr = data修改为let arr = [...data],通过扩展运算符创建数组副本。

修复后完整代码

import BikeCard from "../components/BikeCard";
import Layout from "../components/Layout";
import { getAllBikes } from "../lib/bikes";
import Head from "next/head";
import { useState } from "react";
import BikeGallery from "../components/BikeGallery";

export default function Home({ data }) {
    const allBikes = [];
    data.forEach((model) => model.bikes.forEach((bike) => allBikes.push(bike)));
    const [displayData, setDisplayData] = useState(allBikes);

    const SortByInputHandler = (e) => {
        if (e.target.value === "year") {
            setDisplayData(sortByYear(allBikes));
        } else if (e.target.value === "make") {
            setDisplayData(allBikes);
        }
    };
    const sortByYear = (data) => {
        let arr = [...data];
        arr.sort((a, b) => {
            return b.year > a.year ? 1 : b.year < a.year ? -1 : 0;
        });
        return arr;
    };
    return (
        <Layout>
            <Head>
                <title>Ride 4 - Bikes</title>
            </Head>
            <div>
                <div>
                    <label>排序方式:</label>
                    <select onChange={SortByInputHandler}>
                        <option value="make">品牌</option>
                        <option value="year">年份</option>
                    </select>
                </div>
            </div>
            <BikeGallery displayData={displayData} />
        </Layout>
    );
}

export async function getStaticProps() {
    const data = getAllBikes();
    return {
        props: { data },
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:15:02