👆Привет всем! В этом руководстве мы создадим простое приложение со списком задач с помощью React и хуков через интерфейс Context API Material UI и, наконец, интеграцию с Firebase 🔥


Часть 1: Установки и конфигурации
- Node.js и Npm ( https://nodejs.org/en/download/)
- VSCode (https://code.visualstudio.com/download)
Откройте терминал / cmd и введите:
$ sudo npm install -g create-react-app $ create-react-app todo-list $ cd todo-list
Добавить интерфейс материала
$ npm i --save@material-ui/core$npm install @material-ui/icons
Перейдите в общую папку, откройте файл index.html и введите
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
Добавить генератор UUID
$ npm i --save uuid
Часть 2: Контекстный API
В этой части статьи мы покажем, как использовать и реализовывать контекстный API и редукторы.
Итак, давайте начнем с создания двух папок:
- контексты
- редукторы
Давайте создадим файл TaskContext.js в папке контекста.
Контекст предоставляет способ передавать данные через дерево компонентов без необходимости передавать реквизиты вручную на каждом уровне.
- Создайте функцию компонента стрелки с помощью props:
export const TaskContext = createContext();
const TaskContextProvider = (props) => {
...
}
export default TaskContextProvider;
Затем нам нужно вернуть нашего провайдера с элементами диспетчера и задач, наконец, нам нужно реализовать «отсортированный массив», который возвращает отсортированные задачи по isCheked или Not.
return (
<TaskContext.Provider value={{ tasks,sortedTasks, dispatch }}> {props.children}
</TaskContext.Provider>)
Результат:
2. В папке reducer создайте новый файл reducer под названием TaskReducer.js.
Итак, нам нужен метод 3 действий для работы с нашим массивом задач: первое действие необходимо для добавления новой задачи, второе - для проверки задачи, а третье удалит задачу.
Давайте создадим перечисление для этих статических действий
export const Action = {
ADD_TASK: "add-task",
CHECK_TASK: "check-task",
REMOVE_TASK: "remove-task"
}
Давайте создадим редуктор с корпусом переключателя, чтобы заменить тип действия:
Когда добавление задачи выбрано, правильным способом будет выдвинуть новую задачу.
case Action.ADD_TASK: {
return [...state, action.task]
}
Когда выбран отмеченный тип, нам нужно изменить конкретную задачу в массиве по значению идентификатора задачи.
case Action.CHECK_TASK:{
let taskIndex = state.findIndex(t => t.id === action.task.id);
state[taskIndex].isChecked = action.task.isChecked
return state.filter(task => task.id !== action.id);
}
И удалить задачу будет
case Action.REMOVE_TASK: {
return state.filter(task => task.id !== action.id)
}
Результат:
Часть 3: Компонент, хуки и UI материала
В этой части статьи мы узнаем, как создать компонент стрелочной функции для каждого события задачи.
Давайте создадим папку components в папке src и создадим 4 компонента:
- NavbarComponent.js - src / components / NavbarComponent.js
- AddTaskComponent.js - src / components / TodoListComponent.js.
- TasksListComponent.js - src / components / tasks / AddTaskComponent.js.
- TodoListComponent.js - src / component / tasks / TaskListComponent.js
Примечание: я решил создать еще одну папку в компонентах, называемых задачами.
- Откройте NavbarComponent.js, давайте создадим новый компонент и используем контекст
const NavbarComponent = () => {
const {tasks} = useContext(TaskContext)
}
export default NavbarComponent;
Теперь давайте сделаем навигационную панель, используя материальный интерфейс.
return (
<AppBar position="static">
<Toolbar variant="dense"
style={{ justifyContent: "center" }} >
<Typography
variant="h6"
color="inherit">
React Todo List ({tasks.length})
</Typography>
</Toolbar>
</AppBar>
);
Результат:
Https://gist.github.com/shai-benshimol/6a0872107dc9467a3859a9832b60a95c
2. Давайте создадим простой компонент для добавления новой задачи.
3. Давайте создадим новую функцию компонента - TasksListComponent и реализуем useStyles для фонового списка.
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
backgroundColor: theme.palette.background.transparent,
},
marked: {
textDecoration: 'line-through'
}
}));
Затем нам нужно использовать контекст задачи для возврата данных из редуктора.
const {
sortedTasks,
dispatch,
} = useContext(TaskContext)
Затем верните jsx, используя материальный интерфейс.
return (
<List className={classes.root}>
{sortedTasks.map((task) => {
return (
<ListItem key={task.id}
role={undefined}
dense
button
onClick={() => {
onChecked(task.id, !task.isChecked)
}
}>
<IconButton color="primary">
{
!task.isChecked ? (<CropFreeIcon />) : (<LibraryAddCheckIcon />)
}
</IconButton>
<ListItemText primary={task.description}
className={task.isChecked ? classes.marked : ''} />
<ListItemSecondaryAction>
<IconButton
edge="end"
aria-label="comments"
onClick={() => {
dispatch({
type: Action.REMOVE_TASK,
id: task.id
})
}}>
<DeleteOutlineIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
);
})}
</List>
Результат:
4. Откройте созданный ранее TodoListComponent.js и создайте новый компонент для этого состояния.
В TodoListComponent мы хотим объединить 2 компонента, AddTask и TasksList, в столбец.
Давайте соберем все вместе в App.js… Итак, откройте файл App.js и замените его на
И это все
$ npm run start

Часть 4: Firebase
Я уже создал руководство по интеграции firebase
Создайте список задач с помощью Vuejs, Vuex, Vuetify и Firebase 🔥
🔭Сегодня я собираюсь показать вам, как создать приложение с нуля, используя самый мощный фреймворк SPA Vuejs ”С… medium.com»
Теперь давайте создадим новую папку для firebase с двумя подпапками: firebase.config.js и Firebase.js.
В firebase.config.js просто добавьте свои значения из консоли firebase, как:
import firebase from 'firebase';const firebaseConfig = {
apiKey: "<--->",
authDomain: "<--->",
databaseURL: "<--->",
projectId: "<--->",
storageBucket: "<--->",
messagingSenderId: ""<--->",
appId: "<--->",
measurementId: "<--->"
};firebase.initializeApp(firebaseConfig)export const db = firebase.firestore()
Откройте «Firebase.js» и добавьте 4 функции.
- addTaskReques
- getTasksRequest
- checkTaskRequest
- removeTaskRequest
Добавить запрос задачи:
export const addTaskRequest = async (task) => {
return await db.collection(collection)
.add(task)
}
Получить запрос задач
export const getTasksRequest = async () => {
return await db.collection(collection).get().then(res => {
let tasks = [];
res.docs.map(task => {
let data = task.data();
tasks.push({
id: data.id,
isChecked: data.isChecked,
description: data.description,
created: data.created
})
})
return tasks;
})
}
Проверить запрос задачи
export const checkTaskRequest = (id, isChecked) => {
return db.collection(collection)
.doc(id)
.set({
isChecked: isChecked
})
}
Удалить запрос задачи
export const removeTaskRequest = (id) => {
return await db.collection(collection)
.db.collection(collection)
.doc(id)
.delete()
}
Конечный результат
Часть 5: useEffect
Обработчик эффекта, useEffect, добавляет возможность выполнять побочные эффекты из функционального компонента. Он служит той же цели, что и componentDidUpdate и componentWillUnmount в классах React, но объединен в единый API. (Мы покажем примеры сравнения useEffect с этими методами в Использование обработчика эффектов.)
Теперь давайте внесем некоторые изменения в «TaskComponent.js», создадим массив useState для setTasks из хранилища firebase, а затем создадим хук useEffect следующим образом:
const [sortedTasks,setTasks] = useState([]);
const count = sortedTasks.length;
useEffect(()=>{
getTasksRequest().then(res=>{
setTasks(res.sort((t, f) => (f.isChecked === t.isChecked)? 0 : f.isChecked? -1 : 1))
dispatch({
type:Action.GET_ALL_TASKS,
res
})
})
},[])
Конечный результат
Вывод
Мы узнали, как обрабатывать локальное состояние с помощью Context API и хуков, создавать пользовательский интерфейс с пользовательским интерфейсом материала и хранить данные в облаке firebase.