Sobes.tech
Junior

Ako správne meniť stav komponentov v Reacte?

sobes.tech AI

Odpoveď od AI

Zmena stavu v React prebieha prostredníctvom metódy setState pre triedy komponenty alebo pomocou hooku useState pre funkčné komponenty.

Triedy komponenty:

// Importujeme React
import React, { Component } from 'react';

// Vytvárame triedu komponentu
class MyComponent extends Component {
  // Inicializujeme stav
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  // Metóda na zmenu stavu
  incrementCount = () => {
    // Používame setState
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Počítadlo: {this.state.count}</p>
        <button onClick={this.incrementCount}>Zvýšiť</button>
      </div>
    );
  }
}

// Exportujeme komponent
export default MyComponent;
  • setState je asynchrónny.
  • setState spája nový stav s aktuálnym (shallow merge).
  • setState môže prijímať funkciu, ktorá vracia nový stav založený na predchádzajúcom:
// Metóda na zmenu stavu s použitím funkcie
incrementCountFunction = () => {
  this.setState((prevState) => ({
    count: prevState.count + 1
  }));
};

Funkčné komponenty (s použitím useState):

// Importujeme React a useState
import React, { useState } from 'react';

// Vytvárame funkčný komponent
function MyFunctionComponent() {
  // Inicializujeme stav pomocou useState
  const [count, setCount] = useState(0); // [aktuálny stav, funkcia na aktualizáciu]

  // Funkcia na zmenu stavu
  const incrementCount = () => {
    // Používame funkciu na aktualizáciu stavu
    setCount(count + 1);
  };

  return (
    <div>
      <p>Počítadlo: {count}</p>
      <button onClick={incrementCount}>Zvýšiť</button>
    </div>
  );
}

// Exportujeme komponent
export default MyFunctionComponent;
  • useState vracia pole zo dvoma prvkami: aktuálny stav a funkciu na jeho aktualizáciu.
  • Funkcia na aktualizáciu stavu, ktorú vracia useState, nahrádza aktuálny stav, nezhodnocuje ho.
  • Môžete odovzdať funkciu do funkcie na aktualizáciu stavu, ak závisí od predchádzajúceho:
// Funkcia na zmenu stavu s použitím funkcie
const incrementCountFunction = () => {
  setCount(prevCount => prevCount + 1);
};

Dôležité body pri zmene stavu:

  • Nezmeníte stav priamo: Nikdy nepriraďujte novú hodnotu vlastnosti state priamo (napríklad this.state.count = 5 alebo count = 5). React si nevšimne túto zmenu a komponent sa nepre-renderuje.
  • Zmeny objektov a polí: Pri zmene objektov alebo polí v stave, vždy vytvorte ich nové kópie. React porovnáva odkazy na objekty/polia, a ak sa odkaz nezmení, React predpokladá, že dáta sa nezmenili a nevolá pre-render.
// Zmena objektu v triedykom komponente
this.setState(prevState => ({
  user: {
    ...prevState.user, // Kopírujeme staré vlastnosti
    name: 'Nové meno' // Aktualizujeme požadovanú vlastnosť
  }
}));

// Zmena poľa v funkčnom komponente
setItems(prevItems => [...prevItems, 'Nový prvok']); // Pridávame nový prvok
  • Asynchrónnosť setState: Ak potrebujete vykonať akciu po tom, čo sa stav aktualizuje a komponent pre-renderuje, použite druhý argument setState (funkciu-callback) alebo hook useEffect vo funkčných komponentoch.
// Callback v setState
this.setState({ count: this.state.count + 1 }, () => {
  console.log('Stav je aktualizovaný!');
});
// useEffect na reakciu na zmenu stavu
useEffect(() => {
  console.log('Stav count sa zmenil:', count);
}, [count]); // Závislosť: hook sa spustí pri zmene count

Porovnanie metód:

Charakteristika Trieda komponent (setState) Funkčný komponent (useState)
Syntax Metóda this.setState(newState[, callback]) Hook const [state, setState] = useState(initialState)
Zlučovanie/Nahradzovanie Zlučuje nový stav s aktuálnym (shallow merge) Nahrádza aktuálny stav novým
Asynchrónnosť Asynchrónny Funkcia aktualizácie je asynchrónna pri volaní z obslužných funkcií, ale synchronná pri volaní v rámci render fázy React
Závislosť od predchádzajúceho stavu Odovzdanie funkcie do setState: this.setState(prevState => ({...})) Odovzdanie funkcie do funkcie aktualizácie: setState(prev => ({...}))