React Component UseEffect 不会在 prop 更改时重新渲染
React Component UseEffect isn't rerendering upon prop change
我在 React 中有一个动态倒数计时器:
这个 Timer 是一个组件 (MovementTimer.js) 并且主要组件 (GameRoom.js) 正在调用 Timer 的 render 方法,通过 props 传递。
This is the render Timer function that's being called below upon every GameRoom render
renderTimer = () => {
console.log('*** Timer RERENDER ***');
console.log(this.state.turn_time);
console.log(this.state.last_time);
if(this.state.turn_time != null && this.state.last_time != null){
const props = {
time : this.state.turn_time,
last_time : this.state.last_time
}
return(
<MovementTimer {...props}/>
)
} else {
return(
<p>Undefined Timer.</p>
)
}
}
This is the render method of GameRoom.js
render() {
if(this.state.guest){
console.log('loaded in ! ' + this.state.guest);
// Put into return statement for DEBUG {this.state.turn ? "TRUE" : "FALSE"}
return (
<div className="main">
{this.renderBoard()}
{this.renderTimer()}
{}
<p className="welcome">
{this.state.userResponseData}
{
this.state.guest[0] ? (this.state.turn ? "It's your opponent's turn." : "It's your turn, move!") : (this.state.turn ? "It's your turn, move!" : "It's your opponent's turn.")
}</p>
</div>
)
}
return (
<div className="main">
{this.renderBoard()}
<p className="welcome"> {this.state.turn ? "TRUE" : "FALSE"} Loading {this.state.userResponseData}</p>
</div>
)
}
}
基本上问题是,每当 GameRoom.js 重新渲染时,renderTimer() 函数将更新的道具传递给 MovementTimer,但是计时器不会重置。我试图使用 useRef 状态布尔值,但它有问题并且无法正常工作。
MovementTimer.js component
import React, {useRef, clearState,useState,useCallback} from 'react'
const MovementTimer = (props) => {
console.log('Re initizalized')
const time = parseInt(props.time);
const last_time = parseInt(props.last_time);
//clearState()
console.log(
"Estimated Time:\n"+
((last_time+time*1000) - Date.now() )/1000
);
let [counter, setCounter] = React.useState(Math.round( ((last_time+time*1000) - Date.now() )/1000 ) );
// const reinit = () => {
// setCounter(time)
// }
console.log(counter);
console.log(last_time);
React.useEffect(() => {
counter > 0 && setTimeout(() => setCounter(
counter - 1
), 1000); //Set this too Due time - last time / 1000 (for secs)
if(counter === 0){
const socketProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const socket = new WebSocket(socketProtocol+(window.location.href).split(':')[1]+':5000');
socket.onopen = async () => {
await socket.send(JSON.stringify({
query_type : 't0',
room_id: (window.location.pathname).slice(6)
}));
socket.close();
}
setCounter(Math.round( ((last_time+time*1000) - Date.now() )/1000 ))
}
}, [counter]);
return (
<div>
{counter}
</div>
)
}
export default MovementTimer
这个组件里,我用useEffect做定时器倒计时,传入时差秒数(使用传下来的props) 有没有办法检查props是否变化,重新设置useEffect?
在那条 if 语句中(计数器 === 0),我使用 setCounter 手动将其设置回去。但是我不知道如何检查道具的变化。每当 last_time 道具更新时。
您的 useEffect
中的第二个参数是函数侦听更改的内容。如果您只想在特定变量更改时重新运行 useEffect
中的函数,请将其添加到数组中。例如,如果你想在变量 x
改变时重新运行它,你可以这样写:
React.useEffect(() => { /* do stuff */ }, [counter, x]);
我在 React 中有一个动态倒数计时器:
这个 Timer 是一个组件 (MovementTimer.js) 并且主要组件 (GameRoom.js) 正在调用 Timer 的 render 方法,通过 props 传递。
This is the render Timer function that's being called below upon every GameRoom render
renderTimer = () => {
console.log('*** Timer RERENDER ***');
console.log(this.state.turn_time);
console.log(this.state.last_time);
if(this.state.turn_time != null && this.state.last_time != null){
const props = {
time : this.state.turn_time,
last_time : this.state.last_time
}
return(
<MovementTimer {...props}/>
)
} else {
return(
<p>Undefined Timer.</p>
)
}
}
This is the render method of GameRoom.js
render() {
if(this.state.guest){
console.log('loaded in ! ' + this.state.guest);
// Put into return statement for DEBUG {this.state.turn ? "TRUE" : "FALSE"}
return (
<div className="main">
{this.renderBoard()}
{this.renderTimer()}
{}
<p className="welcome">
{this.state.userResponseData}
{
this.state.guest[0] ? (this.state.turn ? "It's your opponent's turn." : "It's your turn, move!") : (this.state.turn ? "It's your turn, move!" : "It's your opponent's turn.")
}</p>
</div>
)
}
return (
<div className="main">
{this.renderBoard()}
<p className="welcome"> {this.state.turn ? "TRUE" : "FALSE"} Loading {this.state.userResponseData}</p>
</div>
)
}
}
基本上问题是,每当 GameRoom.js 重新渲染时,renderTimer() 函数将更新的道具传递给 MovementTimer,但是计时器不会重置。我试图使用 useRef 状态布尔值,但它有问题并且无法正常工作。
MovementTimer.js component
import React, {useRef, clearState,useState,useCallback} from 'react'
const MovementTimer = (props) => {
console.log('Re initizalized')
const time = parseInt(props.time);
const last_time = parseInt(props.last_time);
//clearState()
console.log(
"Estimated Time:\n"+
((last_time+time*1000) - Date.now() )/1000
);
let [counter, setCounter] = React.useState(Math.round( ((last_time+time*1000) - Date.now() )/1000 ) );
// const reinit = () => {
// setCounter(time)
// }
console.log(counter);
console.log(last_time);
React.useEffect(() => {
counter > 0 && setTimeout(() => setCounter(
counter - 1
), 1000); //Set this too Due time - last time / 1000 (for secs)
if(counter === 0){
const socketProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const socket = new WebSocket(socketProtocol+(window.location.href).split(':')[1]+':5000');
socket.onopen = async () => {
await socket.send(JSON.stringify({
query_type : 't0',
room_id: (window.location.pathname).slice(6)
}));
socket.close();
}
setCounter(Math.round( ((last_time+time*1000) - Date.now() )/1000 ))
}
}, [counter]);
return (
<div>
{counter}
</div>
)
}
export default MovementTimer
这个组件里,我用useEffect做定时器倒计时,传入时差秒数(使用传下来的props) 有没有办法检查props是否变化,重新设置useEffect?
在那条 if 语句中(计数器 === 0),我使用 setCounter 手动将其设置回去。但是我不知道如何检查道具的变化。每当 last_time 道具更新时。
您的 useEffect
中的第二个参数是函数侦听更改的内容。如果您只想在特定变量更改时重新运行 useEffect
中的函数,请将其添加到数组中。例如,如果你想在变量 x
改变时重新运行它,你可以这样写:
React.useEffect(() => { /* do stuff */ }, [counter, x]);