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

React.js中如何使用ref修改循环渲染的多个元素的样式?

问题根因

你为循环渲染的所有div绑定了同一个barRef引用,单值ref在循环赋值过程中会被不断覆盖,最终只会保留最后一个渲染DOM元素的引用,这就是只能修改最后一个div高度的原因。同时你代码里的Math.random(10)写法有误,Math.random()不接收参数,默认返回0~1之间的随机数。

解决方案1:数据驱动渲染(React推荐写法)

React推荐用状态控制视图,不要直接操作DOM。我们可以把所有柱子的高度存入状态数组,点击随机按钮时更新整个数组即可自动同步视图:

import React, { useState } from 'react'
import "../styling/Sorting.css";
import Slider from '@material-ui/core/Slider';

function Sorting() {
    // 滑块值:柱子数量
    const [value, setValue] = useState(0);
    // 存储所有柱子的高度
    const [heights, setHeights] = useState([]);
    
    const changeValue = (event, newValue) => {
        setValue(newValue)
        // 滑块变化时初始化新柱子的默认高度,可自定义
        setHeights(prev => {
            const newHeights = [...prev]
            // 新增柱子时补充默认高度
            while(newHeights.length < newValue) {
                newHeights.push(Math.floor(Math.random() * 500))
            }
            // 减少柱子时截断数组
            return newHeights.slice(0, newValue)
        })
    }

    function randomHeight(){
        // 生成对应数量的随机高度数组
        const newHeights = Array.from({length: value}, () => Math.floor(Math.random() * 500))
        setHeights(newHeights)
    }

    return (
        <div className="container">
            <nav>
                <div className="slider">
                    <Slider value={value} onChange={changeValue} max={30} valueLabelDisplay="on"/>
                </div>
                <div className="random_height">
                    <button onClick={randomHeight}>random</button>
                </div>
            </nav>
            <div className="bars">
                {/* 直接用状态里的高度渲染,不需要操作DOM */}
                {heights.map((height, i) => (
                    <div 
                        className="bar" 
                        key={i} 
                        style={{height: `${height}px`}}
                    ></div>
                ))}
            </div>
        </div>
    )
}

export default Sorting

解决方案2:使用Ref数组(适合需要直接操作DOM的场景)

如果你的业务场景需要直接操作DOM元素,可以用数组存储所有柱子的ref:

import React, { useState, useRef } from 'react'
import "../styling/Sorting.css";
import Slider from '@material-ui/core/Slider';

function Sorting() {
    const [value, setValue] = useState(0);
    
    const changeValue = (event, newValue) => {
        setValue(newValue)
    }

    // 声明ref数组存储所有柱子的DOM引用
    const barRefs = useRef([])

    function randomHeight(){
        // 遍历所有ref设置随机高度
        barRefs.current.forEach(bar => {
            if(bar) {
                const randomH = Math.floor(Math.random() * 500)
                bar.style.height = `${randomH}px`
            }
        })
    }

    return (
        <div className="container">
            <nav>
                <div className="slider">
                    <Slider value={value} onChange={changeValue} max={30} valueLabelDisplay="on"/>
                </div>
                <div className="random_height">
                    <button onClick={randomHeight}>random</button>
                </div>
            </nav>
            <div className="bars">
                {Array.from({ length: value }, (_, i) => (
                    <div 
                        className="bar" 
                        key={i}
                        // 把每个DOM元素存入对应下标的ref位置
                        ref={el => barRefs.current[i] = el}
                    ></div>
                ))}
            </div>
        </div>
    )
}

export default Sorting

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:45:03