Sobes.tech
Junior

Как правилно да променяме състоянието на компонентите в React?

sobes.tech AI

Отговор от AI

Промяната на състоянието в React става чрез метода setState за класови компоненти или с помощта на hook-а useState за функционални компоненти.

Класови компоненти:

// Импортиране на React
import React, { Component } from 'react';

// Създаване на класов компонент
class MyComponent extends Component {
  // Инициализиране на състоянието
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  // Метод за промяна на състоянието
  incrementCount = () => {
    // Използване на setState
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Брояч: {this.state.count}</p>
        <button onClick={this.incrementCount}>Увеличи</button>
      </div>
    );
  }
}

// Експорт на компонента
export default MyComponent;
  • setState е асинхронен.
  • setState обединява новото състояние с текущото (shallow merge).
  • setState може да приема функция, която връща ново състояние, базирано на предишното:
// Метод за промяна на състоянието с използване на функция
incrementCountFunction = () => {
  this.setState((prevState) => ({
    count: prevState.count + 1
  }));
};

Функционални компоненти (с useState):

// Импортиране на React и useState
import React, { useState } from 'react';

// Създаване на функционален компонент
function MyFunctionComponent() {
  // Инициализиране на състоянието с useState
  const [count, setCount] = useState(0); // [текущо състояние, функция за актуализация]

  // Функция за промяна на състоянието
  const incrementCount = () => {
    // Използване на функция за актуализация
    setCount(count + 1);
  };

  return (
    <div>
      <p>Брояч: {count}</p>
      <button onClick={incrementCount}>Увеличи</button>
    </div>
  );
}

// Експорт на компонента
export default MyFunctionComponent;
  • useState връща масив с две стойности: текущото състояние и функция за неговото обновяване.
  • Функцията за обновяване, върната от useState, замества текущото състояние, а не го обединява.
  • Може да се предаде функция във функцията за обновяване, ако новото състояние зависи от предишното:
// Функция за промяна на състоянието с използване на функция
const incrementCountFunction = () => {
  setCount(prevCount => prevCount + 1);
};

Важни моменти при промяна на състоянието:

  • Не променяйте състоянието директно: Никога не присвоявайте нова стойност на свойството state (например this.state.count = 5 или count = 5). React няма да засече тази промяна и компонентът няма да се пререндерира.
  • Промяна на обекти и масиви: При промяна на обекти или масиви в състоянието, винаги създавайте нови копия. React сравнява референциите и ако референцията не се променя, предполага, че данните не са се променили и не извършва пререндер.
// Промяна на обект в класов компонент
this.setState(prevState => ({
  user: {
    ...prevState.user, // Копиране на старите свойства
    name: 'Ново име' // Актуализиране на необходимото свойство
  }
}));

// Промяна на масив във функционален компонент
setItems(prevItems => [...prevItems, 'Нов елемент']); // Добавяне на нов елемент
  • Асинхронност на setState: Ако искате да изпълните действие след като състоянието бъде актуализирано и компонентът пренареди, използвайте втория аргумент на setState (функция callback) или hook-а useEffect във функционалните компоненти.
// Callback в `setState`
this.setState({ count: this.state.count + 1 }, () => {
  console.log('Състоянието е актуализирано!');
});
// `useEffect` за реакция на промяна в състоянието
useEffect(() => {
  console.log('Промени се състоянието count:', count);
}, [count]); // Зависимост: hook-ът ще се активира при промяна на count

Сравнение на методите:

Характеристика Класов компонент (setState) Функционален компонент (useState)
Синтаксис Метод this.setState(newState[, callback]) Hook const [state, setState] = useState(initialState)
Обединяване/Замяна Обединява новото състояние с текущото (shallow merge) Заменя текущото състояние с новото
Асинхронност Асинхронен Асинхронен при извикване от обработчици на събития, но синхронен при рендер фазата на React
Зависимост от предишното състояние Предавайте функция към setState: this.setState(prevState => ({...})) Предавайте функция към setState(prev => ({...}))