Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 2부

15374 단어 dockerreactc
이 문서에서는 React Js 애플리케이션을 만들고 ASP.NET Core Web API 요청을 사용하여 영화 데이터를 가져오는 방법을 설명합니다.
예를 들어 단계별로 살펴보겠습니다.

ASP.NET Core Web API를 생성하려면 이전 기사를 참조하십시오.

이 게시물의 섹션은 다음과 같습니다.

ReactJs 프로젝트 생성
패키지 설치
구성 요소 추가
React UI 애플리케이션 테스트

시작하겠습니다.

ReactJs 프로젝트 만들기:

명령 프롬프트를 열고 React 앱을 생성하려는 경로로 이동합니다.
npx create-react-app movies-app


반응 프로젝트를 생성한 후 Visual Studio 코드를 사용하여 애플리케이션을 엽니다.



터미널로 이동 => 반응 앱 시작
npm start
프로젝트를 시작하면 기본 브라우저에서 UI가 열립니다.



패키지 설치:
  • npm install semantic-ui-react semantic-ui-css



  • index.html 페이지를 열고 헤드 섹션에서 .css 링크를 지나고 본문 섹션 다음에 .js를 엽니다.


  • npm 설치 axios


  • npm install react-toastify



  • 구성 요소 추가

    => src => "Components"폴더 생성으로 이동
  • 구성 요소 => NavBar.jsx

  • 이렇게 하면 애플리케이션에 내비게이션 바가 추가됩니다.

    import { Button, Menu } from "semantic-ui-react";
    import "../index.css";
    
    export default function NavBar(props) {
      return (
        <Menu inverted fixed="top">
          <Menu.Item header>
            <img
              src="/movieslogo.png"
              alt="logo"
              style={{ marginRight: "10px", marginLeft: "10px" }}
            />
            Movies
          </Menu.Item>
          <Menu.Item>
            <Button positive content="Add Movie" onClick={() => props.addForm()} />
          </Menu.Item>
        </Menu>
      );
    }
    


  • 구성 요소 => MoviesTable.jsx

  • 이 구성 요소는 영화 세부 정보 및 영화 삭제 및 편집 작업이 포함된 테이블을 표시합니다.

    import { Fragment } from "react";
    import { Table, Button } from "semantic-ui-react";
    import "../index.css";
    
    export default function MoviesTable(props) {
      return (
        <Fragment>
          <h1 style={{ marginLeft: "30px" }}>Movies List</h1>
          <Table
            celled
            style={{
              marginLeft: "30px",
              marginTop: "30px",
              width: "1100px",
              border: "1px solid black",
            }}
          >
            <Table.Header>
              <Table.Row>
                <Table.HeaderCell>Title</Table.HeaderCell>
                <Table.HeaderCell>Language</Table.HeaderCell>
                <Table.HeaderCell>Year</Table.HeaderCell>
                <Table.HeaderCell>OTT</Table.HeaderCell>
                <Table.HeaderCell>Actions</Table.HeaderCell>
              </Table.Row>
            </Table.Header>
            <Table.Body>
              {props.movies.map((movie) => (
                <Table.Row key={movie.id}>
                  <Table.Cell>{movie.title}</Table.Cell>
                  <Table.Cell>{movie.movieLanguage}</Table.Cell>
                  <Table.Cell>{movie.releaseYear}</Table.Cell>
                  <Table.Cell>{movie.ott}</Table.Cell>
                  <Table.Cell>
                    <Button positive onClick={() => props.editForm(movie)}>
                      Edit
                    </Button>
                    <Button negative onClick={() => props.deleteMovie(movie.id)}>
                      {" "}
                      Delete
                    </Button>
                  </Table.Cell>
                </Table.Row>
              ))}
            </Table.Body>
          </Table>
        </Fragment>
      );
    }
    
    


  • 구성 요소 => AddMovie.jsx

  • 이 구성 요소는 영화 세부 정보를 데이터베이스에 추가하고 영화 테이블에 표시하는 데 사용됩니다.

    import { Button, Form, Segment } from "semantic-ui-react";
    import React, { useState } from "react";
    import { toast } from "react-toastify";
    import "react-toastify/dist/ReactToastify.css";
    export default function AddMovie(props) {
    
      const initialState = {
        title: "",
        movieLanguage: "",
        releaseYear: "",
        ott: "",
      };
    
      const [movie, setMovie] = useState(initialState);
    
      function handleSubmit(e) {
        e.preventDefault();
        if (!movie.title) {
          toast.error("Please fill all the details !", {
            position: toast.POSITION.TOP_RIGHT,
          });
          return;
        }
        props.handleSumbit(movie);
        setMovie(initialState);
      }
    
      function handleInputChange(event) {
        const { name, value } = event.target;
        setMovie({ ...movie, [name]: value });
      }
    
      return (
        <>
          <h1 style={{ marginLeft: "15px" }}>Add Movie</h1>
          <Segment clearing style={{ marginRight: "30px", marginTop: "30px", marginLeft: "10px" }} >
            <Form onSubmit={handleSubmit} autoComplete="off">
              <Form.Input placeholder="Title" value={movie.title} name="title" onChange={handleInputChange} />
              <Form.Input placeholder="Language" value={movie.movieLanguage} name="movieLanguage" onChange={handleInputChange}/>
              <Form.Input placeholder="Year" value={movie.releaseYear} name="releaseYear" onChange={handleInputChange} />
              <Form.Input placeholder="OTT" value={movie.ott} name="ott" onChange={handleInputChange}/>
              <Button floated="right" positive type="submit" content="Submit" />
              <Button floated="right" type="button" content="Cancel" onClick={() => props.closeForm()}
              />
            </Form>
          </Segment>
        </>
      );
    }
    
    


  • 구성 요소 => EditMove.jsx

  • 이 구성 요소는 영화 데이터를 편집하고 업데이트하는 데 사용됩니다.

    import { Button, Form, Segment } from "semantic-ui-react";
    import React, { useState } from "react";
    
    export default function EditMovie(props) {
      const [movie, setMovie] = useState(props.movie);
    
      function handleSubmit(e) {
        e.preventDefault();
        props.handleEditMovie(movie);
      }
    
      function handleInputChange(event) {
        const { name, value } = event.target;
        setMovie({ ...movie, [name]: value });
      }
    
      return (
        <>
          <h1 style={{ marginLeft: "15px" }}>Edit Movie</h1>
          <Segment
            clearing
            style={{ marginRight: "30px", marginTop: "30px", marginLeft: "10px" }}
          >
            <Form onSubmit={handleSubmit} autoComplete="off">
              <Form.Input
                placeholder="Title"
                value={movie.title}
                name="title"
                onChange={handleInputChange}
              />
    
              <Form.Input
                placeholder="Language"
                value={movie.movieLanguage}
                name="movieLanguage"
                onChange={handleInputChange}
              />
              <Form.Input
                placeholder="Year"
                value={movie.releaseYear}
                name="releaseYear"
                onChange={handleInputChange}
              />
    
              <Form.Input
                placeholder="OTT"
                value={movie.ott}
                name="ott"
                onChange={handleInputChange}
              />
              <Form.TextArea
                placeholder="Description"
                value={movie.description}
                name="description"
                onChange={handleInputChange}
              />
              <Button floated="right" positive type="submit" content="Submit" />
              <Button
                floated="right"
                type="button"
                content="Cancel"
                onClick={() => props.closeForm()}
              />
            </Form>
          </Segment>
        </>
      );
    }
    
    


  • 구성 요소 => MoviesDashboard.jsx

  • 이것은 모든 영화 관련 구성 요소를 표시하는 데 사용됩니다.

    import { Grid } from "semantic-ui-react";
    import AddMovie from "./AddMovie";
    import MoviesTable from "./MoviesTable";
    import EditMovie from "./EditMovie";
    
    export default function MoviesDashboard(props) {
      return (
        <Grid>
          <Grid.Column width="10">
            <MoviesTable movies={props.movies} editForm={props.editForm} deleteMovie={props.deleteMovie}/>
          </Grid.Column>
          <Grid.Column width="6">
            {props.showAddForm && (<AddMovie closeForm={props.closeForm} handleSumbit={props.handleSumbit} />)}
            {props.showEditForm && ( <EditMovie movie={props.movie} closeForm={props.closeForm} handleEditMovie={props.handleEditMovie} />  )}
          </Grid.Column>
        </Grid>
      );
    }
    


    아래 코드로 App.js를 업데이트합니다.

    import axios from "axios";
    import "./App.css";
    import { v4 as uuid } from "uuid";
    import NavBar from "./components/NavBar";
    import { useEffect, useState } from "react";
    import MoviesDashboard from "./components/MoviesDashboard";
    import { toast, ToastContainer } from "react-toastify";
    function App() {
      const [movies, setMovies] = useState([]);
      const [movie, setMovie] = useState();
      const [showAddForm, setshowAddForm] = useState(false);
      const [showEditForm, setshowEditForm] = useState(false);
    
      useEffect(() => {
        axios.get("http://localhost:5159/api/movies").then((response) => {
          setMovies(response.data);
        });
      }, [movies]);
    
      function handleEditMovie(movie) {
        axios({
          method: "put",
          url: `http://localhost:5159/api/movies/${movie.id}`,
          data: {
            Id: movie.id,
            Title: movie.title,
            MovieLanguage: movie.movieLanguage,
            ReleaseYear: movie.releaseYear,
            OTT: movie.ott,
          },
          config: {
            headers: {
              Accept: "application/json",
              "Content-Type": "application/json",
            },
          },
        })
          .then((response) => {
            console.log(response);
            toast.success("Movie updated successfully", {
              position: toast.POSITION.TOP_RIGHT,
            });
          })
          .catch((error) => {
            console.log("the error has occured: " + error);
          });
    
        setMovies([...movies, movie]);
      }
    
      function handleSumbit(movie) {
        const data = {
          Id: uuid(),
          Title: movie.title,
          MovieLanguage: movie.movieLanguage,
          ReleaseYear: movie.releaseYear,
          OTT: movie.ott,
        };
        axios({
          method: "post",
          url: "http://localhost:5159/api/movies",
          data: data,
          config: {
            headers: {
              Accept: "application/json",
              "Content-Type": "application/json",
            },
          },
        })
          .then((response) => {
            console.log(response);
            toast.success("Movie added successfully", {
              position: toast.POSITION.TOP_RIGHT,
            });
          })
          .catch((error) => {
            console.log("the error has occured: " + error);
          });
    
        setMovies([...movies, data]);
      }
    
      function addForm() {
        setshowEditForm(false);
        setshowAddForm(true);
      }
    
      function closeForm() {
        setshowAddForm(false);
        setshowEditForm(false);
        setMovie("");
      }
    
      function editForm(movie) {
        setMovie("");
        setshowAddForm(false);
        setshowEditForm(true);
        setMovie(movie);
      }
    
      function deleteMovie(id) {
        setshowEditForm(false);
        setMovie("");
        axios.delete(`http://localhost:5159/api/movies/${id}`).then(() => {
          toast.success("Movie deleted successfully", {
            position: toast.POSITION.TOP_RIGHT,
          });
        });
    
        setMovies([...movies.filter((x) => x.id !== id)]);
      }
    
      return (
        <div>
          <NavBar addForm={addForm} />
          <h1>Movies Data</h1>
          <MoviesDashboard
            movies={movies}
            showAddForm={showAddForm}
            showEditForm={showEditForm}
            editForm={editForm}
            movie={movie}
            deleteMovie={deleteMovie}
            closeForm={closeForm}
            handleSumbit={handleSumbit}
            handleEditMovie={handleEditMovie}
          />
          <ToastContainer position="top-center" />
        </div>
      );
    }
    
    export default App;
    
    


    스타일 지정을 위해 아래 코드로 index.css를 업데이트합니다.

    body {
      background-color: #eaeaea !important;
    }
    .ui.inverted.top.fixed.menu {
      background-image: linear-gradient(135deg,rgb(233, 10, 204) 0%, rgb(155, 50, 133) 69%,rgb(104, 50, 85) 89%) !important;
    }
    


    *무비 UI 테스트 *

    홈페이지:



    영화 추가:





    영화 편집:





    다음 섹션에서는 .NET Core 6.0 Web API 및 React 애플리케이션을 컨테이너화하는 방법을 설명합니다.

    여기에서 전체 프로젝트를 찾을 수 있습니다GitHub repository.

    좋은 웹페이지 즐겨찾기