Create.jsx
import { useState } from "react";
import "./Create.css";
export default function Create() {
const [title, setTitle] = useState("");
const [method, setMethod] = useState("");
const [cookingTime, setCookingTime] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
console.log(title, method, cookingTime);
};
return (
<div className="create">
<h2 className="page-title">새 레시피를 추가하세요</h2>
<form onSubmit={handleSubmit}>
<label>
<span>요리 제목:</span>
<input
onChange={(e) => setTitle(e.target.value)}
type="text"
value={title}
required
/>
</label>
{/* recipe ingredients here */}
<label>
<span>요리 방법:</span>
<textarea
onChange={(e) => setMethod(e.target.value)}
value={method}
required
/>
</label>
<label>
<span>쿠킹 타임 (분):</span>
<input
onChange={(e) => setCookingTime(e.target.value)}
type="number"
value={cookingTime}
required
/>
</label>
<button className="btn">추가</button>
</form>
</div>
);
}
Create.css
.create {
color: #555;
max-width: 480px;
margin: 60px auto;
}
.create label span {
display: block;
margin: 30px 0 10px;
}
.create p {
margin-top: 10px;
font-size: 0.8em;
}
.create button {
display: block;
width: 100px;
font-size: 1em;
color: #fff;
padding: 8px 20px;
border: 0;
border-radius: 4px;
background-color: #58249c;
cursor: pointer;
text-decoration: none;
margin: 20px auto;
}
테스트하기 -> 추가버튼 누르면 form 의 내용들이 출력된다.
현재 위의 레시피 추가 form에는 빠진것이 있다.
server의 DB를 보면 ingredients 즉, 재료이다.
Create.jsx에 추가한다.
const [newIngredient, setNewIngredient] = useState(""); //한 개의 재료
const [ingredients, setIngredients] = useState([]); // 모든 재료
const ingredientInput = useRef(); //특정 태그를 지정한다
//요리 재료 추가
const handleAdd = (e) => {
e.preventDefault();
const ing = newIngredient.trim(); //입력된 재료의 공백 제거
// 새 재료가 모든 재료에 없을 경우 모든 재료에 추가 한다.
if (ing && !ingredients.includes(ing)) {
setIngredients((prev) => [...prev, newIngredient]); //이전 모든 재료에 추가한다.
}
setNewIngredient(""); //한 개의 재료는 공백으로
ingredientInput.current.focus(); //커서를 정해진 태그에 위치
};
{/*요리재료*/}
<label>
<span>요리 재료:</span>
<div className="ingredients">
<input
type="text"
onChange={(e) => setNewIngredient(e.target.value)}
value={newIngredient}
ref={ingredientInput}
/>
<button onClick={handleAdd} className="btn">
사용
</button>
</div>
</label>
<p>
재료들 :{" "}
{ingredients.map((i) => (
<em key={i}>{i}, </em>
))}
</p>
재료를 입력할 때 마다 newIngredient에 추가되고
사용을 누르면 handleAdd 함수가 실행되는데
handleAdd에서 모든 재료 useState(배열)에 추가한다.
아까 레시피 추가 시 작동한 handleSubmit 함수에 재료를 추가한다.
Create.css 추가
.ingredients {
display: flex;
align-items: center;
}
.ingredients button {
margin: 0 0 0 10px;
}
재료들이 추가됨을 확인 할 수 있다.
이제 이 데이터들을 DB에 넣어야한다.
POST를 적지 않으면 GET으로 요청
method 를 POST로 적으면
POST가 적용된다.
import { useState, useEffect } from "react";
export const useFetch = (url, method = "GET") => {
const [data, setData] = useState(null);
const [isPending, setIsPending] = useState(false);
const [error, setError] = useState(null);
const [options, setOptions] = useState(null);
const postData = (postData) => {
setOptions({
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(postData),
});
};
useEffect(() => {
const controller = new AbortController();
const fetchData = async (fetchOptions) => {
setIsPending(true);
try {
const res = await fetch(url, {
...fetchOptions,
signal: controller.signal,
});
if (!res.ok) {
throw new Error(res.statusText);
}
const data = await res.json();
setIsPending(false);
setData(data);
setError(null);
} catch (err) {
if (err.name === "AbortError") {
console.log("the fetch was aborted");
} else {
ㅁ;
setIsPending(false);
setError("Could not fetch the data");
}
}
};
// invoke the function
if (method === "GET") {
fetchData();
}
if (method === "POST" && options) {
fetchData(options);
}
return () => {
controller.abort();
};
}, [url, method, options]);
return { data, isPending, error, postData };
};
Create.jsx
const { postData, data } = useFetch("http://localhost:3030/recipes", "POST");
//레시피 추가
const handleSubmit = (e) => {
e.preventDefault();
postData({ title, ingredients, method, cookingTime: cookingTime + " 분" });
};
DB에도 고구마 맛탕이 추가된게 확인된다.
(세 번 눌러버려서 ㅎ )
데이터가 바뀌면 홈으로 리다이렉트하도록 useEffect를 추가한다.
'FRONTEND > React' 카테고리의 다른 글
[쿠킹레시피] Context 와 Provider 만들어 적용하기, 리듀서 함수 적용 (1) | 2023.11.24 |
---|---|
[쿠킹레시피] 검색창 컴포넌트 및 검색 결과 출력 (0) | 2023.11.24 |
[쿠킹레시피] 제이슨 서버에서 데이터 가져오기 및 레시피 리스트 컴포넌트 생성 (2) | 2023.11.24 |
[쿠킹레시피] 라우터 사용 및 네브바 컴포넌트 생성 (1) | 2023.11.24 |
[쿠킹레시피] 프로젝트 세팅 및 제이슨 서버 설치 (1) | 2023.11.24 |