Lodash 延迟函数不允许我看到被调用函数中的状态
Lodash delay function doesn't let me to see state inside called function
我正在使用 lodash 的延迟函数在特定时间段后调用我的函数 3 次,但出于某种原因,我在该函数中看不到更新的 React 状态。
这可能是什么原因?
import React, { useEffect, useState } from 'react';
import Delays from './helper';
import { delay } from 'lodash';
const App = () => {
const [progress, setProgress] = useState(0);
console.log(progress); // Here I can see the updated state
const testFunction = () => {
console.log('inside function', progress); // here I can't see the updated state
};
useEffect(() => {
const seconds = 40;
const attempts = 3;
const milliseconds = 4000;
setInterval(() => {
setProgress((prevProgress) =>
prevProgress >= 100 ? 100 : prevProgress + 1
);
}, seconds * attempts * 10); // 1200
for (let i = 0; i < attempts; i++) {
delay(testFunction, milliseconds * (i + 1));
}
}, []);
return <div>Hello World</div>;
};
export default App;
对我来说奇怪的是,如果我使用基于 class 的方法,那么我没有任何问题,状态值将出现在我的函数中。
import React, { Component } from 'react';
import Delays from './helper';
import { delay } from 'lodash';
class App extends Component {
state = {
progress: 0,
};
udpateProgress = (value) => {
this.setState({ progress: value });
};
testFunction = () => {
console.log('inside function', this.state.progress); // here I can see the Updated state
};
componentDidMount = () => {
const seconds = 40;
const milliseconds = 4000;
const attempts = 3;
setInterval(() => {
this.udpateProgress(
this.state.progress >= 100 ? 100 : this.state.progress + 1
);
}, seconds * attempts * 10); // 1200
for (let i = 0; i < attempts; i++) {
delay(this.testFunction.bind(this), milliseconds * (i + 1));
}
};
render() {
console.log('inside render', this.state.progress);
return <div>Hello World</div>;
}
}
export default App;
问题
这里的问题是您已经关闭了 testFunction
中的初始 progress
状态值,您正在从 useEffect
循环过来,在组件安装时运行一次。
一个解决方案
一种解决方案是使用 React ref 来保存当前状态值,然后您可以在 testFunction
.
中引用该值
function App() {
const [progress, setProgress] = useState(0);
const progressRef = useRef(); // <-- ref to hold state value
const testFunction = () => {
console.log('inside function', progressRef.current); // <-- reference state value
};
useEffect(() => {
console.log(progress); // <-- log per update
progressRef.current = progress; // <-- cache state value
}, [progress])
useEffect(() => {
const seconds = 40;
const attempts = 3;
const milliseconds = 4000;
const timer = setInterval(() => { // <-- don't forget to save ref to interval timer
setProgress((prevProgress) =>
prevProgress >= 100 ? 100 : prevProgress + 1
);
}, seconds * attempts * 10); // 1200
for (let i = 0; i < attempts; i++) {
delay(testFunction, milliseconds * (i + 1));
}
return () => clearInterval(timer); // <-- to clear when component unmounts!!!
}, []);
return <div>Hello World</div>;
}
我正在使用 lodash 的延迟函数在特定时间段后调用我的函数 3 次,但出于某种原因,我在该函数中看不到更新的 React 状态。 这可能是什么原因?
import React, { useEffect, useState } from 'react';
import Delays from './helper';
import { delay } from 'lodash';
const App = () => {
const [progress, setProgress] = useState(0);
console.log(progress); // Here I can see the updated state
const testFunction = () => {
console.log('inside function', progress); // here I can't see the updated state
};
useEffect(() => {
const seconds = 40;
const attempts = 3;
const milliseconds = 4000;
setInterval(() => {
setProgress((prevProgress) =>
prevProgress >= 100 ? 100 : prevProgress + 1
);
}, seconds * attempts * 10); // 1200
for (let i = 0; i < attempts; i++) {
delay(testFunction, milliseconds * (i + 1));
}
}, []);
return <div>Hello World</div>;
};
export default App;
对我来说奇怪的是,如果我使用基于 class 的方法,那么我没有任何问题,状态值将出现在我的函数中。
import React, { Component } from 'react';
import Delays from './helper';
import { delay } from 'lodash';
class App extends Component {
state = {
progress: 0,
};
udpateProgress = (value) => {
this.setState({ progress: value });
};
testFunction = () => {
console.log('inside function', this.state.progress); // here I can see the Updated state
};
componentDidMount = () => {
const seconds = 40;
const milliseconds = 4000;
const attempts = 3;
setInterval(() => {
this.udpateProgress(
this.state.progress >= 100 ? 100 : this.state.progress + 1
);
}, seconds * attempts * 10); // 1200
for (let i = 0; i < attempts; i++) {
delay(this.testFunction.bind(this), milliseconds * (i + 1));
}
};
render() {
console.log('inside render', this.state.progress);
return <div>Hello World</div>;
}
}
export default App;
问题
这里的问题是您已经关闭了 testFunction
中的初始 progress
状态值,您正在从 useEffect
循环过来,在组件安装时运行一次。
一个解决方案
一种解决方案是使用 React ref 来保存当前状态值,然后您可以在 testFunction
.
function App() {
const [progress, setProgress] = useState(0);
const progressRef = useRef(); // <-- ref to hold state value
const testFunction = () => {
console.log('inside function', progressRef.current); // <-- reference state value
};
useEffect(() => {
console.log(progress); // <-- log per update
progressRef.current = progress; // <-- cache state value
}, [progress])
useEffect(() => {
const seconds = 40;
const attempts = 3;
const milliseconds = 4000;
const timer = setInterval(() => { // <-- don't forget to save ref to interval timer
setProgress((prevProgress) =>
prevProgress >= 100 ? 100 : prevProgress + 1
);
}, seconds * attempts * 10); // 1200
for (let i = 0; i < attempts; i++) {
delay(testFunction, milliseconds * (i + 1));
}
return () => clearInterval(timer); // <-- to clear when component unmounts!!!
}, []);
return <div>Hello World</div>;
}