Состояние и хуки — это сердце любого React-приложения. Если вы хотите создать что-то большее, чем просто статичный экран, вам придётся разобраться, как управлять состоянием компонентов. Сегодня мы погрузимся в useState и useEffect, два самых часто используемых хука в React Native.

Что такое состояние (state)?

Представьте, что у вас есть приложение с кнопкой «Нравится». Нажатие на кнопку увеличивает счётчик лайков. Состояние — это как раз то, что хранит это значение (например, количество лайков). В React Native состояние позволяет нам хранить данные, которые могут изменяться в ходе работы приложения.

React автоматически обновляет интерфейс, когда состояние изменяется. Вам не нужно вручную говорить: «Эй, обнови экран». Вы просто меняете состояние, и React всё делает за вас.

Что такое хуки (hooks)?

Хуки (hooks) — это функции, которые позволяют вам «подключать» функциональность React, такую как состояние или жизненный цикл, к функциональным компонентам. До появления хуков в 2018 году для этого нужно было использовать классовые компоненты.

Два важных хука:

  • useState: Используется для создания и управления состоянием внутри функционального компонента.
  • useEffect: Используется для выполнения побочных эффектов: работа с API, таймеры, подписки на события и т. д.

Хук useState

Хук useState создаёт состояние внутри компонента.

Синтаксис

const [state, setState] = useState(initialValue);
  • state — текущее значение состояния.
  • setState — функция, которая обновляет значение состояния.
  • initialValue — начальное значение состояния.

Пример: счётчик

import React, { useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const Counter = () => {
  const [count, setCount] = useState(0); // Инициализация состояния с начальным значением 0

  return (
    <View style={styles.container}>
      <Text style={styles.text}>Счётчик: {count}</Text>
      <Button title="Увеличить" onPress={() => setCount(count + 1)} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  text: { fontSize: 24, marginBottom: 10 },
});

export default Counter;

Хук useEffect

useEffect позволяет выполнять действия (или «эффекты») после рендеринга. Это может быть вызов API, настройка таймеров или подписка на события.

Синтаксис

useEffect(() => {
  // Код эффекта
  return () => {
    // Очистка эффекта (опционально)
  };
}, [dependencies]);
  • Функция внутри useEffect вызывается после каждого рендера.
  • Массив зависимостей [] говорит, когда эффект должен быть выполнен:
  • Если массив пуст, эффект выполнится только один раз (аналог componentDidMount).
  • Если массив содержит переменные, эффект выполнится всякий раз, когда эти переменные изменятся.

Пример: таймер

import React, { useState, useEffect } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const Timer = () => {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds((prev) => prev + 1);
    }, 1000);

    return () => clearInterval(interval); // Очищаем таймер при размонтировании
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.text}>Секунд прошло: {seconds}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  text: { fontSize: 24 },
});

export default Timer;

Практика: создаём экран с таймером

Теперь, когда мы знаем основы useState и useEffect, давайте реализуем экран таймера. У нас будет три кнопки:

  • Старт — запускает таймер.
  • Стоп — останавливает таймер.
  • Сброс — сбрасывает значение таймера на 0.

Код приложения:

import React, { useState, useEffect } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const TimerApp = () => {
  const [seconds, setSeconds] = useState(0); // Состояние для хранения времени
  const [isRunning, setIsRunning] = useState(false); // Состояние для управления таймером

  useEffect(() => {
    let interval;

    if (isRunning) {
      interval = setInterval(() => {
        setSeconds((prev) => prev + 1); // Увеличиваем секунды на 1 каждую секунду
      }, 1000);
    }

    // Очистка таймера при остановке или размонтировании
    return () => clearInterval(interval);
  }, [isRunning]); // Эффект срабатывает при изменении isRunning

  const resetTimer = () => {
    setSeconds(0); // Сбрасываем время
    setIsRunning(false); // Останавливаем таймер
  };

  return (
    <View style={styles.container}>
      <Text style={styles.timer}>{seconds} сек</Text>
      <View style={styles.buttonContainer}>
        <Button
          title={isRunning ? 'Стоп' : 'Старт'}
          onPress={() => setIsRunning(!isRunning)} // Переключение состояния
        />
        <Button title="Сброс" onPress={resetTimer} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f5f5f5',
  },
  timer: {
    fontSize: 48,
    marginBottom: 20,
    fontWeight: 'bold',
  },
  buttonContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    width: '60%',
  },
});

export default TimerApp;

Что мы сделали?

  • Состояние для времени (seconds): Это состояние хранит количество секунд, прошедших с момента старта.
  • Состояние для запуска/остановки (isRunning): Это состояние управляет логикой таймера (запущен или остановлен).
  • useEffect для работы с таймером: Мы создали эффект, который запускает интервал, если isRunning равно true. При изменении состояния или размонтировании компонента таймер очищается.

Три кнопки:

  1. Старт: запускает таймер.
  2. Стоп: останавливает таймер.
  3. Сброс: сбрасывает время на 0 и останавливает таймер.
 

Комментарии

0

Без регистрации и смс