问题描述
我正在使用 Less css 生成一个随机数,但它只生成一次随机数,直到浏览器再次刷新。
App.css
@color: blue;
// @random: (Math.round(Math.random() * 100));
@random: percentage(`Math.random()`);
.circle {
position: absolute;
border: solid 4px @color;
border-radius: 50%;
top: @random;
left: @random;
height: 3em;
width: 3em;
background-color: @color;
animation: circleSize 0.5s;
}
和
App.js
function App() {
const [date,setDate] = useState('')
const [circleBoolean,setCircleBoolean] = useState(false);
let random_number;
useEffect(() => {
const interval = setInterval(() => {
doThings()
},2000);
return () => clearInterval(interval);
},[circleBoolean]);
function doThings() {
setCircleBoolean(!circleBoolean);
setDate(moment().format('MMMM Do YYYY,h:mm:ss a')) ;
random_number = Math.random()*100;
console.log("cirlce boolean :" + circleBoolean)
}
console.log("cirlce boolean outside:" + circleBoolean)
return (
<div className="App">
<div className="bg">
<div style={{top:random_number+"%"},{left:random_number+"%"}} className={circleBoolean ? "circle" : ""} />
<div className="card">
<p className="card-info">{date}</p>
</div>
</div>
</div>
);
}
在每次渲染期间添加和删除圆类,并且在这些渲染期间随机数不会改变。如何让它在每次渲染时生成随机数?
解决方法
所以听着,我不知道你为什么要持有两个随机数(一个在 .css 文件中,另一个在组件本身中)。
当您在浏览器中刷新时,css 中的 @random 只会计算一次。您可以使用 styled-components 之类的东西根据组件中的状态使样式动态化。
另一种解决方法是在组件内覆盖(正如您所做的那样)左侧和顶部样式:
const App = () => {
const [date,setDate] = useState('');
const [circleBoolean,setCircleBoolean] = useState(false);
const [randomNumber,setRandom] = useState();
useEffect(() => {
const interval = setInterval(() => {
doThings();
},2000);
return () => clearInterval(interval);
},[]);
function doThings() {
setRandom(() => {
return Math.random() * 100;
});
setCircleBoolean((prev) => {
return !prev;
});
setDate(moment().format('MMMM Do YYYY,h:mm:ss a'));
}
return (
<div className="App">
<div className="bg">
<div style={{ top: randomNumber + '%',left: randomNumber + '%' }} className={circleBoolean ? 'circle' : ''} />
<div className="card">
<p className="card-info">{date}</p>
</div>
</div>
</div>
);
};
在这里,我更改了您的“样式”道具并将 random_number 移动到其自己的状态 randomNumber。
老 -----
首先,每当 circleBoolean 改变时,你的 useEffect 就会被触发,每两秒一次。 然后它会再次被调用并创建另一个间隔,依此类推。在这里,您需要一个 零依赖项 的数组用于您的 useEffect。这样,一旦组件第一次渲染,间隔将只创建一次。
好的,那么间隔函数将每两秒执行一次 setCircleBoolean 中的状态更改。这样做的正确方法(在这种情况下)是:
setCircleState((prev) => {
return !prev;
});
这样,React 将等待状态变化并更准确地触发重新渲染。