Home > database >  Change variable value only when a state changes in React
Change variable value only when a state changes in React

Time:04-29

I have the code below. How can I reset the stocksHelper, instatiating again when the component render on stocks's useState change?

I need this class to instantiate again to reset the variables inside the class instance, because when the stocks change a calculation needs to be done to render the stocks again. And if I get the instance of the last render with the old values this calculation will bug my entire aplication

export default function Heatmap() {
    const [stocks, setStocks] = useState<IStock[]>([]);
    const stocksHelper: StocksHelper = new StocksHelper(stocks);

    return (
        <main className={styles.main}>
            <RegisterForm stocks={stocks} setStocks={setStocks} />
        </main>
    );
}

RegisterForm component below:

    export default function RegisterForm(props: Props) {
    const { stocks, setStocks } = props;
    const [name, setName] = useState<string>('');
    const [value, setValue] = useState<number>(0);
    const [volume, setVolume] = useState<number>(0);

    function storeStock(): void {
        axios.post('any url', {
            name: name,
            value: value,
            volume: volume
        })
            .then((res) => {
                setStocks([...stocks, res.data]);
            })
            .catch((res) => console.log(res));
    }

    return (
        <form className={styles.form} onSubmit={() => storeStock()}>
            <fieldset>
                <legend className={styles.title}>Cadastro</legend>
                <input type="text" onChange={e => setName(e.target.value)} placeholder="Nome" />
                <input type="number" onChange={e => setValue(parseFloat(e.target.value))} placeholder="Porcentagem" />
                <input type="number" onChange={e => setVolume(parseInt(e.target.value))} placeholder="Volume" />
                <button type='submit'>Cadastrar</button>
            </fieldset>
        </form>
    );
}

CodePudding user response:

If I'm understanding correctly, you might be able to achieve this with useEffect! See below for an example:

export default function Heatmap() {
    const [stocks, setStocks] = useState<IStock[]>([]);
    const [stocksHelper, setStockHelper] = useState<StocksHelper>(new StocksHelper(stocks));

    useEffect(() => {
        setStockHelper(new StocksHelper(stocks))
    }, [stocks])

    return (
        <main className={styles.main}>
            <RegisterForm stocks={stocks} setStocks={setStocks} />
        </main>
    );
}

CodePudding user response:

@AmitMaraj's answer is perfectly fine but for a shorter and more concise method you should use useMemo:

const stocksHelper = useMemo(() => new StocksHelper(stocks), [stocks]);

Now a new StocksHelper will only be created when stocks changes.

Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.

Link to documentation

  • Related