Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 2부
예를 들어 단계별로 살펴보겠습니다.
ASP.NET Core Web API를 생성하려면 이전 기사를 참조하십시오.
이 게시물의 섹션은 다음과 같습니다.
ReactJs 프로젝트 생성
패키지 설치
구성 요소 추가
React UI 애플리케이션 테스트
시작하겠습니다.
ReactJs 프로젝트 만들기:
명령 프롬프트를 열고 React 앱을 생성하려는 경로로 이동합니다.
npx create-react-app movies-app
반응 프로젝트를 생성한 후 Visual Studio 코드를 사용하여 애플리케이션을 엽니다.
터미널로 이동 => 반응 앱 시작
npm start
프로젝트를 시작하면 기본 브라우저에서 UI가 열립니다.
패키지 설치:
index.html 페이지를 열고 헤드 섹션에서 .css 링크를 지나고 본문 섹션 다음에 .js를 엽니다.
구성 요소 추가
=> src => "Components"폴더 생성으로 이동
이렇게 하면 애플리케이션에 내비게이션 바가 추가됩니다.
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>
);
}
이 구성 요소는 영화 세부 정보 및 영화 삭제 및 편집 작업이 포함된 테이블을 표시합니다.
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>
);
}
이 구성 요소는 영화 세부 정보를 데이터베이스에 추가하고 영화 테이블에 표시하는 데 사용됩니다.
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>
</>
);
}
이 구성 요소는 영화 데이터를 편집하고 업데이트하는 데 사용됩니다.
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>
</>
);
}
이것은 모든 영화 관련 구성 요소를 표시하는 데 사용됩니다.
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.
Reference
이 문제에 관하여(Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 2부), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jayavardhan5555/react-and-net-core-60-sample-project-with-docker-part-2-1ml0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)