在React中使用“外部”变量来记住不同渲染之间的值

问题描述 投票:0回答:1

我正在学习 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 />}
        
        </>
    )
}
javascript reactjs design-patterns
1个回答
0
投票

@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

© www.soinside.com 2019 - 2024. All rights reserved.