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

React中如何将更新后的对象传递给子组件并触发重渲染?

React排序后State未更新、UI不渲染的问题分析与解决

核心问题原因

  1. 原地排序导致引用未变:Array.sort()是原地修改数组的方法,你在sortVotes中直接对newArticles执行排序后,数组的内存引用并没有改变。React的State更新依赖浅比较,当传入setNewArticles的是同一个引用时,React会判定State没有变化,因此不会触发组件重渲染。
  2. 列表Key值不唯一:子组件Articles中,列表项的key使用了固定值"article-index",这违反了React对Key的要求——Key必须是列表中每个元素的唯一标识,会导致React无法正确追踪列表项的变化,可能引发渲染异常。

解决方法

1. 复制数组后再排序,生成新引用

修改sortVotes函数,先通过扩展运算符或slice()复制原数组,再对新数组排序,确保传入setNewArticles的是全新的数组引用:

function sortVotes() {
    // 用扩展运算符复制原数组,避免修改原State
    const sorted = [...newArticles].sort((a,b) => b.upvotes - a.upvotes); // b-a实现降序,符合"最多点赞"的需求
    setNewArticles(sorted);
}

也可以用slice()实现复制:

const sorted = newArticles.slice().sort((a,b) => b.upvotes - a.upvotes);

2. 修复列表项的Key值

在Articles组件的map循环中,使用每个文章的唯一属性组合作为Key(比如标题+日期,确保唯一性):

props.articles.map((article) => {
    return <tr data-testid="article" key={`${article.title}-${article.date}`}>
        <td>{article.title}</td>
        <td>{article.upvotes}</td>
        <td>{article.date}</td>
    </tr>
})

3. 可选:初始化State时复制Props数组

为了避免意外修改传入的Props数组(比如后续Props动态更新的场景),初始化State时最好复制一份Props数组:

const [newArticles, setNewArticles] = useState([...articles]);

修改后的完整代码

App.js

import React, { useState } from 'react';
import './App.css';
import Articles from './components/Articles';

const title = "Sorting Articles";

function App({articles}) {
    // 初始化时复制Props数组,隔离State与Props
    const [newArticles, setNewArticles] = useState([...articles]);

    function sortVotes() {
        // 生成新数组后排序,保证State引用更新
        const sorted = [...newArticles].sort((a,b) => b.upvotes - a.upvotes);
        setNewArticles(sorted);
    }

    return (
        <div className="App">
            <h8k-navbar header={title}></h8k-navbar>
            <div>
                <label>Sort By</label>
                <button onClick={sortVotes} className="small">Most Upvoted</button>
            </div>
            <Articles articles={newArticles}/>
        </div>
    );
}

export default App;

Articles.js

import React from 'react';

function Articles(props) {
    return (
        <div>
            <table>
                <thead>
                <tr>
                    <th>Title</th>
                    <th>Upvotes</th>
                    <th>Date</th>
                </tr>
                </thead>
                <tbody>
                    {
                        props.articles.map((article) => {
                            return <tr data-testid="article" key={`${article.title}-${article.date}`}>
                                <td>{article.title}</td>
                                <td>{article.upvotes}</td>
                                <td>{article.date}</td>
                            </tr>
                        })
                    }
                </tbody>
            </table>
        </div>
    );
}

export default Articles;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:57:35