React Native: Создаем Todo List (Урок 5)

Структура проекта

Приложение разделено на компоненты для улучшения читаемости и сопровождаемости кода: Header (шапка), ListItem (элемент списка) и Form (форма добавления задач). Компоненты расположены в папке components в файлах header.js, listItem.js и form.js.

Компонент Header (header.js)

Компонент Header отображает заголовок «Список дел».

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

const Header = () => {
  return (
    <View style={styles.main}>
      <Text style={styles.text}>Список дел</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  main: {
    paddingTop: 50,
    height: 100,
    backgroundColor: 'silver',
    alignItems: 'center',
    justifyContent: 'center'
  },
  text: {
    fontSize: 18,
    color: 'red',
    textAlign: 'center'
  }
});

export default Header;

Стили задают отступ сверху (50px), высоту (100px), серый фон, размер шрифта (18px), красный цвет текста и центрирование текста.

Подключение Header в App.js

Компонент Header импортируется и используется в основном файле App.js:

import React from 'react';
import { View } from 'react-native';
import Header from './components/header';

const App = () => {
  return (
    <View>
      <Header />
      {/* Остальной контент приложения */}
    </View>
  );
};

export default App;

Вывод списка задач (App.js)

Массив задач и функция для его управления создаются с помощью useState из react. FlatList используется для вывода списка:

import React, { useState } from 'react';
import { View, FlatList, Text } from 'react-native';
import Header from './components/header';

const App = () => {
  const [listOfItems, setListOfItems] = useState([
    { id: '1', text: 'Купить молоко' },
    { id: '2', text: 'Помыть машину' },
    { id: '3', text: 'Купить картошку' },
    { id: '4', text: 'Стать миллионером' },
  ]);

  return (
    <View>
      <Header />
      <FlatList
        data={listOfItems}
        renderItem={({ item }) => <Text>{item.text}</Text>}
        keyExtractor={(item) => item.id}
      />
    </View>
  );
};

export default App;

renderItem отображает текст задачи, а keyExtractor использует id как уникальный ключ.

Компонент ListItem (listItem.js)

Компонент ListItem отображает отдельную задачу. TouchableOpacity обеспечивает обработку нажатия.

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

const ListItem = ({ item, deleteHandler }) => {
  return (
    <TouchableOpacity onPress={() => deleteHandler(item.id)} style={styles.item}>
        <Text style={styles.text}>{item.text}</Text>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  item: {
    padding: 20,
    marginTop: 20,
    borderColor: 'black',
    borderWidth: 1,
    borderRadius: 5,
    backgroundColor: 'white',
    width: '60%',
    marginLeft: '20%',
  },
  text: {
    textAlign: 'center',
  },
});

export default ListItem;

Подключение ListItem и обработка удаления (App.js)

ListItem импортируется в App.js. deleteHandler удаляет задачу из списка.

import React, { useState } from 'react';
import { View, FlatList } from 'react-native';
import Header from './components/header';
import ListItem from './components/listItem';

const App = () => {
  // ... useState и addHandler (описаны ниже) ...

  const deleteHandler = (id) => {
    setListOfItems((prevItems) => prevItems.filter((item) => item.id !== id));
  };

  return (
    <View>
      <Header />
      <FlatList
        data={listOfItems}
        renderItem={({ item }) => <ListItem item={item} deleteHandler={deleteHandler} />}
        keyExtractor={(item) => item.id}
      />
    </View>
  );
};

export default App;

Компонент Form (form.js)

Компонент Form позволяет добавлять новые задачи.

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

const Form = ({ addHandler }) => {
  const [text, setText] = useState('');

  const onChangeText = (val) => {
    setText(val);
  };

  const pressHandler = () => {
    addHandler(text);
    setText('');
  };

  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        placeholder='Впишите задачу...'
        onChangeText={onChangeText}
        value={text}
      />
      <Button title='Добавить задачу' onPress={pressHandler} color="green"/>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 20,
    paddingTop: 30,
    paddingBottom: 30,
    marginLeft: '20%',
    width: '60%',
  },
  input: {
    borderColor: 'black',
    borderWidth: 1,
    padding: 10,
    marginBottom: 10,
  },
});

export default Form;

Подключение Form и обработка добавления (App.js)

Form импортируется и подключается в App.js. addHandler добавляет новую задачу.

import React, { useState } from 'react';
import { View, FlatList } from 'react-native';
import Header from './components/header';
import ListItem from './components/listItem';
import Form from './components/form';

const App = () => {
  const [listOfItems, setListOfItems] = useState([
    { id: '1', text: 'Купить молоко' },
    { id: '2', text: 'Помыть машину' },
    { id: '3', text: 'Купить картошку' },
    { id: '4', text: 'Стать миллионером' },
  ]);

  const addHandler = (text) => {
    setListOfItems((prevItems) => [
      { id: Math.random().toString(), text },
      ...prevItems,
    ]);
  };

  // ... deleteHandler ...

  return (
    <View>
      <Header />
      <Form addHandler={addHandler} />
      <FlatList
        data={listOfItems}
        renderItem={({ item }) => <ListItem item={item} deleteHandler={deleteHandler} />}
        keyExtractor={(item) => item.id}
      />
    </View>
  );
};

export default App;

Урок демонстрирует создание приложения «Список дел» с использованием компонентов React Native, управления состоянием с помощью useState, FlatList и обработчиков событий.

Что будем искать? Например,программа