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

React数组交换后useEffect未触发函数重新渲染的问题求助

问题解决:React数组交换后柱状图未重新渲染

核心问题分析

  1. 普通变量无法触发React渲染:原代码用var arr声明数组,属于普通变量,React不会追踪其变化,交换元素后组件不会重新渲染。
  2. swap函数逻辑无效:原swap函数仅交换了参数的局部副本,并未修改原数组。
  3. 冗余的bar函数与useEffect误用:每次组件渲染都会重建bar函数,导致useEffect依赖项不稳定;且useEffect中调用bar()无法触发组件渲染,渲染由React自动管理。
  4. 缺失key属性:map遍历元素时未设置key,影响React的diff算法,导致渲染异常。

修正后的完整代码

App.jsx

import './App.css';
import Bar from './components/Bar';
import Footer from './components/Footer';
import Header from './components/Header';
import { useState } from 'react';

function App() {
  // 使用useState将数组转为状态变量,让React追踪变化
  const [arr, setArr] = useState([10, 20, 30, 40, 50, 60]);
  
  // 实现正确的数组交换,通过创建新数组保证状态不可变性
  const swap = (array, x, y) => {
    const newArr = [...array];
    [newArr[x], newArr[y]] = [newArr[y], newArr[x]];
    return newArr;
  };

  const change = () => {
    // 更新状态,触发组件重新渲染
    setArr(prevArr => swap(prevArr, 0, 4));
  };
  
  const wid = 4;
  const delay = 2;

  return (
    <div>
      <Header/>
      <button onClick={change} style={{ color: 'red' }}>Swap</button>
      <Bar/>
      <div className='array'>
        {arr.map((val, idx) => (
          <div
            key={idx} // 添加key属性,帮助React识别元素
            className='element-bar'
            style={{
              height: `${val}px`,
              width: `${wid}px`,
              backgroundColor: "red",
              transition: `${delay}ms`
            }} 
          />
        ))}
      </div>
      <Footer/>
    </div>
  );
}

export default App;

CSS(保持原代码不变)

body {
    background-color: black;
}
.array {
    position: fixed;
    text-align: center;
    left: 250px;
    top: auto;
    bottom: 50px;
    display: flex;
    align-items: flex-end;
    flex-wrap: nowrap;
    width: 1260px;
}

.element-bar {
    display: inline-block;
    margin: 0 auto;
}

.sideNavbar {
    text-align: center;
    height: 100%;
    width: 210px;
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    background-color: rgb(29, 29, 29);
    overflow-x: hidden;
    padding-top: 20px;
    box-shadow: 0 4px 8px 0 rgba(81, 81, 81, 0.7), 0 6px 20px 0 rgb(81, 81, 81,0.7);
}

.sideNavbar h3 {
    font-size: 23px;
    text-decoration: underline;
    color: #818181;
    display: block;
    transition: 0.4s;
}

.sideNavbar h3:hover {
    color: #f1f1f1;
}

.sliderLabel {
    color: #f1f1f1;
}

.btn {
    margin: 10px 0;
    display: inline-block;
    padding: 6px;
    width: 100px;
    color: #818181;
    font-weight: 400;
    border: 2px solid #818181;
    background-color: transparent;
    text-transform: uppercase;
    cursor: pointer;
    border-radius: 100px;
    transition: 0.4s;
}

.btn:hover {
    color: #f1f1f1;
    border: 2px solid #f1f1f1;
    box-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
    text-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
}

.btndisabled {
    margin: 10px 0;
    display: inline-block;
    padding: 6px;
    width: 100px;
    border-radius: 100px;
    font-weight: 400;
    background-color: transparent;
    cursor: not-allowed;
    text-transform: uppercase;
    color: #f1f1f1;
    border: 2px solid #f1f1f1;
    box-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
    text-shadow: 0 12px 16px 0 rgba(81, 81, 81, 0.7), 0 17px 50px 0 rgba(81, 81, 81, 0.7);
}

关键修正说明

  • 状态化数组:用useState声明数组,通过setArr更新状态,触发React组件重新渲染。
  • 不可变更新:创建新数组而非直接修改原数组,符合React状态更新的不可变性原则。
  • 简化渲染逻辑:直接在JSX中使用map渲染元素,去掉冗余的bar函数,避免不必要的函数重建。
  • 添加key属性:为map遍历的元素设置唯一key,保证React diff算法正确工作。
  • 移除无用useEffect:状态变化后组件自动重新渲染,无需手动调用渲染函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 19:30:52