我正在学习 React。我有一个自动递增的计数器。用户可以使用按钮取消计数器组件,并使用相同的按钮可以重新渲染组件,在这种情况下,我希望计数器从之前的值恢复。我用一个全局变量 counterInitial 变量来解决(确切地说是一个私有变量,因为它位于模块内部)。 我想知道这是否是正确的模式,或者我应该使用替代技术。
这是Counter.js:
import React from 'react';
let counterInitial =0;
export default class Counter extends React.Component {
constructor(props) {
super(props);
this.state={count:counterInitial};
console.log("Sono nel costruttore qui")
}
componentDidMount(){
let self=this;
requestAnimationFrame(function run(){
self.timerId=setTimeout(()=>{self.setState({count:self.state.count+1});self.animaFrame=requestAnimationFrame(run)},1000);
})
}
componentWillUnmount(){
clearTimeout(this.timerId);
cancelAnimationFrame(this.animaFrame);
}
render() {
counterInitial = this.state.count;
return (
<p>Valore contatore: {this.state.count}</p>
)
}
}
这是CounterController.js
import { useState } from "react"
import Counter from "./Counter"
export default function CounterController(){
const [contatoreRunning,setContatoreRunning]=useState(true);
const changeCounterState = ()=>{
setContatoreRunning(!contatoreRunning);
}
return (
<>
<button onClick={changeCounterState}>{contatoreRunning?"Stop":"Avvia"}</button>
{contatoreRunning && <Counter />}
</>
)
}
@ilkerkaran 建议我我的代码是反模式。这是代码的重构版本:
CounterController.js:
import { useState } from "react"
import Counter from "./Counter"
export default function CounterController(){
const [contatoreRunning,setContatoreRunning]=useState(true);
const [stateInitial,setStateInitial]=useState(0);
const changeCounterState = ()=>{
setContatoreRunning(!contatoreRunning);
}
return (
<>
<button onClick={changeCounterState}>{contatoreRunning?"Stop":"Avvia"}</button>
{contatoreRunning && <Counter initialState={stateInitial} setInitialState={setStateInitial}/>}
</>
)
}
计数器.js
import React from 'react';
export default class Counter extends React.Component {
constructor(props) {
super(props);
this.state={count:props.initialState};
console.log("Sono nel costruttore qui")
}
componentDidMount(){
let self=this;
requestAnimationFrame(function run(){
self.timerId=setTimeout(()=>{self.setState({count:self.state.count+1});self.animaFrame=requestAnimationFrame(run)},1000);
})
}
componentWillUnmount(){
clearTimeout(this.timerId);
cancelAnimationFrame(this.animaFrame);
this.props.setInitialState(this.state.count);
}
render() {
return (
<p>Valore contatore: {this.state.count}</p>
)
}
}
这里的想法是在父组件(CounterController)中保留计数器的初始值,并在子组件(Counter.js)中设置它。为此,我将 initialState 和 setInitialState 从父组件传递给子组件(此模式称为 lifting state up)