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

如何实现点击按钮对JSON数组按年份、名称排序并切换升降序

实现方案

你之前的写法有三个核心问题:

  1. 按钮的value是硬编码的固定空值,每次点击触发事件拿到的value永远是空,逻辑判断永远只会走到第一个分支,自然不会切换状态
  2. Array.sort()是原地排序方法,直接修改原数组会引发不可预期的渲染问题,排序前建议先对原数组做浅拷贝
  3. 之前的标题排序直接返回布尔值,不符合sort回调需要返回数字的规范,多语言场景下建议用localeCompare处理字符串排序更稳妥

你可以按如下逻辑改造代码:

第一步:调整state结构

用一个对象同时存储当前排序字段和排序方向,方便切换逻辑处理:

import { useState } from 'react';

// 组件内定义state
const [sortConfig, setSortConfig] = useState({
  field: null, // 可选值:'year' 按年份排序 / 'title' 按名称排序
  direction: 'asc' // 可选值:'asc' 升序 / 'desc' 降序
});

第二步:编写按钮点击处理逻辑

两个按钮分别对应年份和名称排序,点击同一个按钮时自动切换排序方向:

// 年份排序按钮点击处理
const handleYearSort = () => {
  setSortConfig(prev => {
    // 如果当前已经是按年份排序,就翻转排序方向
    if (prev.field === 'year') {
      return {
        ...prev,
        direction: prev.direction === 'asc' ? 'desc' : 'asc'
      }
    }
    // 如果之前不是按年份排序,默认按升序(从旧到新)开始排序
    return {
      field: 'year',
      direction: 'asc'
    }
  })
}

// 名称排序按钮点击处理
const handleTitleSort = () => {
  setSortConfig(prev => {
    if (prev.field === 'title') {
      return {
        ...prev,
        direction: prev.direction === 'asc' ? 'desc' : 'asc'
      }
    }
    return {
      field: 'title',
      direction: 'asc'
    }
  })
}

第三步:调整排序渲染逻辑

排序前先浅拷贝原数组,避免修改原数据,同时优化排序回调逻辑:

const showResults = [...movies] // 浅拷贝原数组,避免原地修改
.sort((a, b) => {
  const { field, direction } = sortConfig;
  // 没有选择排序字段时返回0,保持原顺序
  if (!field) return 0;

  let compareResult = 0;
  if (field === 'year') {
    compareResult = a.Year - b.Year;
  } else if (field === 'title') {
    // 用localeCompare处理字符串排序,支持中英文混合场景
    compareResult = a.Title.localeCompare(b.Title);
  }

  // 如果是降序,就把比较结果取反
  return direction === 'asc' ? compareResult : -compareResult;
})
.map((movie, idx) => (
  <div key={idx}>
    <div>
      <h4>{movie.Year}</h4>
      <h3>{movie.Title}</h3>
    </div>
  </div>
));

第四步:渲染切换按钮

还可以动态修改按钮文案,直观显示当前排序状态:

{/* 年份排序按钮 */}
<button onClick={handleYearSort}>
  按年份排序
  {sortConfig.field === 'year' && (
    <span>{sortConfig.direction === 'asc' ? ' 从旧到新' : ' 从新到旧'}</span>
  )}
</button>

{/* 名称排序按钮 */}
<button onClick={handleTitleSort}>
  按名称排序
  {sortConfig.field === 'title' && (
    <span>{sortConfig.direction === 'asc' ? ' A-Z' : ' Z-A'}</span>
  )}
</button>

如果不需要同时显示当前排序状态,直接去掉按钮内的条件渲染部分即可,点击切换逻辑不受影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:09:04