首页 > 解决方案 > 反应自定义表格排序

问题描述

我正在尝试在 React 中实现自定义表格排序,以便在单击标题时进行排序。

单击标题后,该组件不会使用新的帖子数组呈现。为什么?我试图在不使用框架或库的情况下使其工作。

谢谢

*** 我用一个选项更新了代码,第一次单击按 asc 排序,第二次单击更改为 desc。排序全乱了。我的排序功能或我保留最后一个排序选项的地图有问题吗?

import React, {useEffect, useState} from 'react';
import axios from 'axios';

const url = 'https://jsonplaceholder.typicode.com/posts';

const Sort = () => {
    const [posts, setPosts] = useState([]);
    
    const keySort = new Map();
    keySort.set("id", 0);
    keySort.set("title", 0);
    keySort.set("body", 0);

    useEffect(() => {
        async function fetchData() {
            const data = await axios.get(url);
            if(data.status !== 200) 
                console.error(data.statusText);
            else {
                setPosts(data.data);
            }
        }
        fetchData();
    }, []);

    const handleHeaderClick = (event) => {
        const id = event.target.id;
        setPosts((currPosts) => [...currPosts].sort((a,b) => {
            const keySortState = keySort.get(id) || 0;
            if(keySortState >= 0) {
                keySort.set(id, -1)
                if(a[id] > b[id])   return 1
                if(a[id] < b[id])   return -1
                return 0;
            }
            keySort.set(id, 0)
            if(a[id] > b[id])   return -1
            if(a[id] < b[id])   return 1
            return 0;   
        }));
    }

    return (
        <>
            <p>Sort Page</p>
            <table style={{border: '1px solid'}}>
                <thead>
                    <tr>
                        <th id="id" onClick={handleHeaderClick}>id</th>
                        <th id="title" onClick={handleHeaderClick}>Title</th>
                        <th id="body" onClick={handleHeaderClick}>Body</th>
                    </tr>
                </thead>
                <tbody>
                    {posts.map((obj, index) => {
                        return (
                            <tr key={index}>
                                <td>{obj.id}</td>
                                <td>{obj.title}</td>
                                <td>{obj.body}</td>
                            </tr>
                        )
                    })}
                </tbody>
            </table>
        </>
    );
}

export default Sort;

标签: reactjssorting

解决方案


在 React 中改变状态时,你永远不应该改变原始状态对象。您的错误在于这一行const data = posts;,您传递data了的引用posts并因此修改了原始对象。相反,您应该发送setState一个回调函数,该函数接受当前posts数组然后传播它 -...并按照您想要的方式修改它。你可以在React 官方文档中阅读为什么传递函数更好setState

它应该看起来如何:

  const handleHeaderClick = (event) => {
    const id = event.target.id;
    setPosts((currPosts) => [...currPosts].sort((a,b) => b[id] - a[id]));
}

推荐阅读