Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Состояние и события

Состояние в React Native работает так же, как в вебе: useState хранит данные, обработчики событий их меняют, и экран перерисовывается. Соберём из прошлых уроков работающий список задач.

Тип задачи и состояние

Каждая задача — объект с id, названием и отметкой о выполнении. Перепишите app/index.tsx:

// app/index.tsx
import { useState } from 'react';
import { Button, StyleSheet, Text, TextInput, View } from 'react-native';
 
type Task = { id: string; title: string; done: boolean };
 
export default function Index() {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [title, setTitle] = useState('');
 
  function addTask() {
    if (title.trim() === '') return;
    setTasks([...tasks, { id: Date.now().toString(), title: title.trim(), done: false }]);
    setTitle('');
  }
 
  return (
    <View style={styles.screen}>
      <TextInput
        style={styles.input}
        value={title}
        onChangeText={setTitle}
        placeholder="Новая задача"
        onSubmitEditing={addTask}
      />
      <Button title="Добавить" onPress={addTask} />
      {tasks.map((task) => (
        <Text key={task.id} style={styles.task}>
          {task.title}
        </Text>
      ))}
    </View>
  );
}
 
const styles = StyleSheet.create({
  screen: { flex: 1, padding: 16, gap: 8 },
  input: { borderWidth: 1, borderColor: '#ccc', borderRadius: 8, padding: 12 },
  task: { fontSize: 18, paddingVertical: 6 },
});

Введите «Купить хлеб» и нажмите «Добавить» или клавишу ввода на клавиатуре — строка появится под кнопкой, а поле очистится. Пустое название не добавляется.

Отметка о выполнении

Обернём строку в Pressable: короткое нажатие переключает done. Добавьте функцию внутрь компонента и замените вывод списка:

// app/index.tsx
function toggleTask(id: string) {
  setTasks(tasks.map((t) => (t.id === id ? { ...t, done: !t.done } : t)));
}
 
{tasks.map((task) => (
  <Pressable key={task.id} onPress={() => toggleTask(task.id)}>
    <Text style={[styles.task, task.done && styles.done]}>{task.title}</Text>
  </Pressable>
))}

Добавьте Pressable в импорт из react-native и стиль done: { color: '#999', textDecorationLine: 'line-through' }. Нажатие на задачу зачёркивает её, повторное — снимает отметку.

Удаление с подтверждением

На телефоне перед удалением принято спрашивать подтверждение. Alert.alert принимает заголовок, текст и массив кнопок:

// app/index.tsx
function confirmDelete(task: Task) {
  Alert.alert('Удалить задачу?', task.title, [
    { text: 'Отмена', style: 'cancel' },
    {
      text: 'Удалить',
      style: 'destructive',
      onPress: () => setTasks(tasks.filter((t) => t.id !== task.id)),
    },
  ]);
}

Передайте её в Pressable: onLongPress={() => confirmDelete(task)}. Удерживайте палец на задаче — появится окно с кнопками «Отмена» и «Удалить».

Частая ошибка

Изменять массив состояния напрямую:

// app/index.tsx
// Неправильно:
tasks.push({ id: '1', title, done: false });
setTasks(tasks);

React получает тот же массив и не перерисовывает экран — задача не появится. Всегда создавайте новый массив: [...tasks, newTask], map, filter, как разбиралось в курсе React.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.