React组件重渲染时如何每次生成随机数?解决Less变量随机数仅首次渲染生效问题
Got it, let's break down why this is happening and how to fix it! The core issue here is that Less variables are pre-compiled—your @random value gets calculated once when your styles are built (during your project's build step), and it never changes after that, no matter how many times your React component re-renders. To get dynamic, per-update random values, we need to move the random number logic into React (where state updates trigger re-renders) and pass those values to your styles at runtime.
Here are two solid solutions:
1. Use Inline Styles for Dynamic Dimensions
We'll handle the random height directly in React's state, then apply it as an inline style on the circle element. This keeps the dynamic value tied to your component's state updates.
Updated React Code:
function App() { const [date, setDate] = useState('') const [circleBoolean, setCircleBoolean] = useState(false); const [randomPosition, setRandomPosition] = useState(0); const [randomHeight, setRandomHeight] = useState(0); // Track random height in state useEffect(() => { const interval = setInterval(() => { doThings() }, 1000); return () => clearInterval(interval); }, []); function doThings() { setCircleBoolean(prev => !prev); setDate(moment().format('MMMM Do YYYY, h:mm:ss a')) ; // Generate new random values for position and height const newPosition = Math.random() * 100; const newHeight = Math.random() * 100; // Adjust range as needed (e.g., 50-150 for bigger circles) setRandomPosition(newPosition); setRandomHeight(newHeight); } return ( <div className="App"> <div className="bg"> <div style={{ top: `${randomPosition}%`, left: `${randomPosition}%`, height: `${randomHeight}px` // Apply dynamic height here }} className={circleBoolean ? "circle" : ""} /> <div className="card"> <p className="card-info">{date}</p> </div> </div> </div> ); }
Updated Less Code:
Remove the @random variable since we're handling height dynamically now:
@color: blue; .circle { position: absolute; border: solid 4px @color; border-radius: 50%; width: 3em; background-color: @color; animation: circleSize 1s ease-in-out; } @keyframes circleSize { 0% { transform: scale(0, 0); } 50% { transform: scale(1,1); } 100%{ transform: scale(0,0); } }
2. Use CSS Custom Properties (Recommended for Style Separation)
If you prefer to keep most of your styling in Less, use CSS custom properties (variables) to pass the dynamic random value from React to your styles. This keeps your style logic centralized while still allowing runtime updates.
Updated React Code:
Add a CSS variable to the circle element's inline style:
function App() { const [date, setDate] = useState('') const [circleBoolean, setCircleBoolean] = useState(false); const [randomPosition, setRandomPosition] = useState(0); const [randomHeight, setRandomHeight] = useState(0); useEffect(() => { const interval = setInterval(() => { doThings() }, 1000); return () => clearInterval(interval); }, []); function doThings() { setCircleBoolean(prev => !prev); setDate(moment().format('MMMM Do YYYY, h:mm:ss a')) ; const newPosition = Math.random() * 100; const newHeight = Math.random() * 100; setRandomPosition(newPosition); setRandomHeight(newHeight); } return ( <div className="App"> <div className="bg"> <div style={{ top: `${randomPosition}%`, left: `${randomPosition}%`, '--random-height': `${randomHeight}px` // Define CSS variable here }} className={circleBoolean ? "circle" : ""} /> <div className="card"> <p className="card-info">{date}</p> </div> </div> </div> ); }
Updated Less Code:
Reference the CSS variable in your .circle class:
@color: blue; .circle { position: absolute; border: solid 4px @color; border-radius: 50%; height: var(--random-height); // Use the dynamic CSS variable width: 3em; background-color: @color; animation: circleSize 1s ease-in-out; } @keyframes circleSize { 0% { transform: scale(0, 0); } 50% { transform: scale(1,1); } 100%{ transform: scale(0,0); } }
Why This Works
Less is a preprocessor, so all its variables are resolved once during compilation. React, on the other hand, manages runtime state—every time you update state (like randomHeight), the component re-renders and passes the new value to the DOM. Using inline styles or CSS custom properties lets us bridge that gap, making your random height update every second right alongside your other state changes.
内容的提问来源于stack exchange,提问作者mahaveer jeevagan

