Фаза 2: Портфельный проект


****

Здравствуйте. Я рад сообщить о своем первом проекте «Реакция»!
требования к проекту как у меня :

  1. Вы должны сделать одностраничное приложение (только один index.html
    файл) с помощью create-react-app.

  2. Ваше приложение должно использовать по крайней мере 5 компонентов таким образом, чтобы сохранить
    чтобы код был хорошо организован.

  3. Должно быть не менее 3 маршрутов на стороне клиента с использованием React
    Маршрутизатор. Обязательно включите навигационную панель или другой элемент пользовательского интерфейса, который
    позволяет пользователям перемещаться между маршрутами.

  4. Используйте json-сервер для создания RESTful API для вашего бэкенда и
    сделайте GET и POST запросы к json-серверу. Используйте
    форму для выполнения запроса на отправку, в частности, управляемую
    форму/компонент. Кроме того, вы можете использовать
    данные из внешнего API, но это не обязательно.

  5. Добавьте немного стиля: вам рекомендуется написать свой CSS с
    с нуля, либо используя стилизованные компоненты, либо написав CSS
    файлы и использовать id/className для стилизации элементов. Вы можете
    также использовать фреймворк пользовательского интерфейса (например, React Bootstrap,
    Semantic UI или Material UI), если вы предпочитаете.

INTRO

Прежде чем приступить к работе над проектом, давайте вкратце познакомимся с React, чтобы понять, с чем мы работаем.

что такое React

React — это декларативная, эффективная и гибкая библиотека JavaScript, созданная Facebook, чтобы помочь сделать веб-приложения быстрыми и эффективными с минимальными усилиями по кодированию.

Простота в изучении и использовании

React поставляется с отличной документацией и учебниками. Любой, кто знает JavaScript, может без труда освоить React и начать использовать его всего за несколько недель.

Многократно используемые компоненты

React позволяет разработчику разделить приложение на более мелкие компоненты, которые могут быть использованы повторно, тем самым сокращая кодовую базу.

виртуальный DOM
Для любого фреймворка манипуляция DOM является одной из самых сложных задач, особенно когда приложение большое. React решает эту проблему с помощью виртуального DOM, который в основном является облегченной копией реального DOM. Это лишь представление в памяти, которое не отображается на экране.

Вместо того, чтобы снова отображать весь DOM, React сравнивает изменения в Virtual DOM и затем аналогично отображает их в Real DOM.

проект фаза2 (кофейня )

Давайте начнем говорить о процессе нашего проекта теперь, когда мы выяснили, что такое реакт и насколько он функционален.

В этом блоге мы создадим простое приложение React, которое можно использовать для публикации/удаления/обновления списка кофеен.

Настройка

Для создания приложения я использовал npx create-react-app coffee-shop-phase2-project. Затем я использовал cd coffee-shop-phase2-project для доступа к репозиторию приложений, code . для открытия приложения в Visual Studio и npm start для его загрузки в браузере.

После этого я удалил следующие файлы:

  • src/App.css

  • src/App.test.js

  • src/logo.svg

  • src/setupTests.js

Затем я изменил файл App.js так, чтобы он выглядел следующим образом:

Для этого проекта я использовал Material UI, фантастическую библиотеку для написания CSS-в-JS. Возможно, вы захотите использовать ее, если будете повторять мои шаги. Запуститеnpm install @material-ui/core, чтобы получить ее. Однако вы можете использовать и обычный CSS. Это не имеет никакого значения.

После этого шага я начал создавать другие необходимые компоненты, такие как Crad.js, Home.js, ItemForm.js, MenuList и NavBar, используя команду touch component-name.

Компонент App

Компонент<App/> должен был стать главным компонентом (родительским компонентом). У него будет одно поле состояния, поэтому я импортировал useState из react, используя import React, {useState} from "react" Затем я объявил переменную state, оставив компонент App.js следующим образом:

Компонент Menulist

Компонент <App/> затем передавал рассветные элементы как реквизит компоненту <Menulist/>, который затем отображал массив элементов и выводил отдельный компонент для каждого.
Я использовал Material UI в этом компоненте, чтобы стилизовать карточки с помощью сеток, это выглядело следующим образом:

Компонент Cards

Я сосредоточился в основном на стилизации моих карточек в этом компоненте, и я разрушил элемент, который был передан в качестве propas из компонента <Menulist/>, чтобы я мог поместить каждую из них в нужную область.
После этого компонент карточек выглядел следующим образом:

JSON-файл

Следующим моим шагом здесь было создание Json-файла, поскольку это одно из требований лаборатории, которую я решил создать и начать работу над своими fetch-запросами, прежде чем переходить к компоненту <itemForm />.

Компонент ItemForm

Поскольку наш json-файл уже готов, мы можем создавать наши запросы на выборку. Первый, над которым я хочу поработать, это запрос post в моей <itemform/>. Это не лучший вариант для начала; возможно, вы захотите начать с get-запроса, но поскольку мой компонент формы элемента будет отвечать только за отправку данных в бэкенд, я решил начать с него.

Первым шагом является создание функции handleAddItem в компоненте App/>, затем передайте всю функцию в качестве props компоненту ItemForm/>.

После передачи функции handle add пришло время установить состояние данных элементов, импортировав usestate из react с помощью import React useState from "react"; а также импортировав инструменты стилизации из Matrial UI. После установки состояния, стилизации и отправки запроса на выборку компонент <ItemForm/> должен выглядеть следующим образом:

import React, { useState } from "react";
import { FormControl, Input, InputLabel, Button, makeStyles } from '@material-ui/core'



const useStyles = makeStyles((theme) => ({
  root: {
    "& > *": {
      margin: theme.spacing(5),

    }
  }
}));

const image = "https://images5.alphacoders.com/905/905439.jpg"
const styles = {
  container: {
    backgroundImage: `url(${image})`,
    backgroundRepeat: "no-repeat",
    backgroundSize: "contain",
    height: "100vh",
    width: "cover",
    backgroundSize: "cover",
    backgroundPosition: 'center',

  },
}

function ItemForm({ handleAddItem }) {
  const [name, setName] = useState("");
  const [description, SetDescription] = useState("")
  const [image, setImage] = useState("")
  const [price, setPrice] = useState("")

  function handleSubmit(e) {
    e.preventDefault();

    const itemData = {
      name: name,
      image: image,
      description: description,
      price: `${price}$`,
      isInCart: false,
    };
  //clear all input values in the form
  setName('');
  SetDescription('');
  setImage('');
  setPrice('');





    // console.log("name:", name);
    // console.log("discribtion:", discribtion);

    fetch(" http://localhost:3001/coffies", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(itemData),
    })
      .then((r) => r.json())
      .then((newItem) => handleAddItem(newItem));


  }

  const classes = useStyles();



  return (
    <>

      <form className={classes.root} onSubmit={handleSubmit}>
        <FormControl

        >
          <InputLabel>Name</InputLabel>
          <Input
            value={name}
            onChange={(e) => setName(e.target.value)} />
        </FormControl>
        <FormControl>
          <InputLabel>image_url</InputLabel>
          <Input
            value={image}
            onChange={(e) => setImage(e.target.value)} />
        </FormControl>

        <FormControl variant="outlined" color="white">
          <InputLabel>description</InputLabel>
          <Input
            value={description}
            onChange={(e) => SetDescription(e.target.value)}
            label="describtion"
          />
        </FormControl>
        <FormControl variant="outlined">
          <InputLabel>price</InputLabel>
          <Input
            id="component-filled"
            value={price}
            onChange={(e) => setPrice(e.target.value)}
            label="price"
          />
        </FormControl>
        <Button color="primary" type="submit"
          style={{ top: 15, right: 20 }}
        >Add to List</Button>
      </form>

      <div style={styles.container}>

      </div>
    </>
  );
}

export default ItemForm;
Вход в полноэкранный режим Выход из полноэкранного режима

*Запрос Get/Detete/Patch Ftech*.

Последнее, что мне нужно было сделать на этом этапе, это выполнить запросы fetch get/delete в компоненте <App/>.

  1. Запрос Get :

В данном случае требуется хук useEffect, поэтому первым шагом будет его импорт из React с помощью import React, {useEffect, useState} from "react"; затем запрос get:

useEffect(() => {
        fetch("http://localhost:3001/coffies")
            .then((r) => r.json())
            .then((items) => setItems(items));
    }, []);
Войти в полноэкранный режим Выйти из полноэкранного режима

В результате выполнения запроса Get наш браузер будет выглядеть следующим образом:

  1. Запрос Delete:

Функция запроса на удаление (в данном случае функция handleDeletetItem) примет id в качестве аргумента и отправит запрос на удаление определенного id. После второго .then массив элементов будет итерироваться, возвращая только те, которые не соответствуют id запроса на удаление.

function handleDeleteItem(id) {
        fetch(` http://localhost:3001/coffies/${id}`, {
            method: "DELETE",
        })
            .then((r) => r.json())
            .then(() => {
                const updatedQuestions = items.filter((item) => item.id !== id);
                setItems(updatedQuestions);
            })


    }
Вход в полноэкранный режим Выход из полноэкранного режима

Эта функция handleDeleteItem будет передана dawn как реквизит компоненту <Menulist/>, который затем передаст dawn компоненту <Card/>, оставив компонент <Card/> без внимания.

  1. Запрос «Патч:

Запрос Patch будет расположен в компоненте <Cards/>, потому что именно здесь находится кнопка Add to card, и я хотел изменить текстовое содержимое кнопки при каждом нажатии на нее, а также изменить значение isInCart с false на true,

Для того чтобы наше состояние обновлялось с изменяющимися значениями, мы должны создать функцию в компоненте App под названием handleUpdateItem, которая будет проходить через массив элементов и возвращать обновленное значение каждого элемента.

 function handleUpdateItem(updatedItem) {
        const updatedItems = items.map((item) => {
            if (item.id === updatedItem.id) {
                return updatedItem;
            } else {
                return item;
            }
        });
        setItems(updatedItems);
    }
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем эта функция будет передана в качестве параметра компоненту карты, который будет использовать ее для обновления значения состояния в соответствии с запросом исправления, сделанным здесь.

import React from 'react';
import { Card, CardActions, CardContent, Button, CardMedia, Typography } from "@material-ui/core";


function Cards({ item, handleDeleteItem, handleUpdateItem }) {

    const { id, description, name, image, price } = item


    function handleDeleteClick() {
        handleDeleteItem(id)

    }

    function handleAddToCartClick() {

        fetch(`http://localhost:3001/coffies/${item.id}`, {
            method: "PATCH",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                isInCart: !item.isInCart,
            }),
        })
            .then((r) => r.json())
            .then((updatedItem) => handleUpdateItem(updatedItem));
    }


    return (


        <Card
        >


            <CardMedia
                component="img"
                height="350"
                image={image}
            />
            <CardContent>
                <Typography gutterBottom variant="h5" component="div">
                    {name}
                </Typography>
                <Typography variant="body2" color="text.secondary">
                    {description}
                </Typography>
                <Typography>
                    {price}
                </Typography>
            </CardContent>
            <CardActions>
                <Button size="small" className={item.isInCart ? "remove" : "add"} onClick={handleAddToCartClick}>
                    {item.isInCart ? "Remove From" : "Add to"}</Button>
                <Button size="small" onClick={handleDeleteClick}>delete</Button>
            </CardActions>
        </Card>

    );
}
export default Cards

Войти в полноэкранный режим Выйти из полноэкранного режима

Компонент NavBar :

Я знаю, что сказал ранее, что это было «последнее, что мне нужно было сделать», но это была грязная ложь. Мне все еще нужно было создать способ для пользователя перемещаться между компонентами браузера, и мне нужно было установить React Router. Для этого я запустил npm install react-router-dom в терминале.
После этого я импортировал Link из react-router-dom и стилизовал его под Matrial UI.

Это будет выглядеть следующим образом:

import React from "react";
import { Link } from "react-router-dom"
import { makeStyles, AppBar, Toolbar, Typography, CssBaseline } from "@material-ui/core"

const useStyles = makeStyles((theme) => ({
    navlinks: {
        marginLeft: theme.spacing(10),
        display: "flex",
    },
    link: {
        textDecoration: "none",
        color: "white",
        fontSize: "20px",
        marginLeft: theme.spacing(20),
        "&:hover": {
            color: "yellow",
            borderBottom: "1px solid white",
        },
    },
    logo: {
        flexGrow: "1",
        cursor: "pointer",
    },

    title: {
        flexGrow: 5
    }
}));


function NavBar() {
    const classes = useStyles();


    return (


        <AppBar position="static">
            <CssBaseline />
            <Toolbar>
                <Typography variant="h6" className={classes.logo}>
                    <h3 className={classes.title}> The Friendly Bean Coffee Shope</h3>
                </Typography>
                <div className={classes.navlinks} >
                    <nav>
                        <Link to="/"className={classes.link}>Home</Link>
                        <Link to="/ItemForm"className={classes.link}>ItemForm</Link>
                        <Link to="/MenuList"className={classes.link}>Menulist</Link>
                    </nav>
                </div>

            </Toolbar>
        </AppBar>


    );
}

export default NavBar;
Вход в полноэкранный режим Выход из полноэкранного режима

В компоненте App нам также необходимо импортировать Switch и Route из Rreact router dom import { Switch, Route } from "react-router-dom"; возврат этого компонента будет выглядеть следующим образом:

 return (

        <div>
            <NavBar  />
            <Switch>
                <Route exact path="/">
                    <Home />
                </Route>

                <Route path="/MenuList">
                    <MenuList handleDeleteItem={handleDeleteItem} items={items} handleUpdateItem={handleUpdateItem} />
                </Route>
                <Route path="/ItemForm">
                    <ItemForm handleAddItem={handleAddItem} />
                </Route>
                <Route path="*">
                    <h1>404 not found</h1>
                </Route>

            </Switch>

        </div>
    );
Вход в полноэкранный режим Выход из полноэкранного режима

Мы еще не закончили; требуется еще один шаг, чтобы он правильно функционировал в нашемindex.js Мы должны импортировать BrowserRouter из react router Dom import BrowserRouter from'react-router-dom; и разместить его вокруг нашего компонента App, как показано на рисунке:

После этого, когда мы запустим npm start, страница нашего браузера будет выглядеть следующим образом:

Этот опыт многому меня научил. Это была не самая сложная задача, но она позволила мне использовать множество различных возможностей React и потребовала много размышлений о том, как создавать компоненты. Мне также понравилось, как я смог развить свои способности к стилизации, используя material ui, это была самая интересная часть всего этого.
Спасибо за прочтение, вы можете проверить мою ссылку на git hub для получения более подробной информации.

https://github.com/vatimetou-ebeke/Coffee-shop-phase2-project

Оцените статью
Procodings.ru
Добавить комментарий