Week 1レビュー
23885 ワード
Day 1/Emotion練習
これはflexの練習に対する課題で、どこがどれだけ不足しているのかをもう一度知りました.
小さな塊に割ってdivを捕まえてspace-binterとpaddingの値を捕まえて、
borderを使用する場合は、lineだけでdivをキャプチャする必要はありません.
どうやってdivを捕まえるのか...先生のコメントを聞いて、もう一度確認しました.
初めてreactに触れて、どのように使うべきか分からず、同僚の助けでよく応用しました.
私にとって、これは非常に困難な課題で、難しすぎると思って、深夜まで続けて、フンフン、
わずか1週間後の今、私は再び彼を見て、私はもっとよくできる自信があります.
Day 2/Stateの利用
stateを使用した会員入力フォームの作成
import { useState } from 'react'
import { Warn,
Wrapper,
Title } from '../../../styles/signup'
export default function SignupStatePage(){
const [email, setEmail] = useState("")
const [emailError, setEmailError] = useState("")
const [password, setPassword] = useState("")
const [passwordCheck, setPasswordCheck] = useState("")
const [passwordError, setPasswordError] = useState("")
function onChangeEmail(event){
console.log(event.target.value)
// event.target => 태그전체 <input type="text" ...
// event.target.value => 우리가 입력한 값 [email protected]
setEmail(event.target.value)
}
function onChangePassword(event){
setPassword(event.target.value)
}
function onChangePasswordCheck(event){
setPasswordCheck(event.target.value)
// setPasswordError(event.target.value !== password)
}
function onClickSignup(){
// 진짜 포장이 잘 됐는지 확인해보기
console.log(email)
console.log(password)
console.log(passwordCheck)
if(email.includes("@") === false){
setEmailError("이메일이 올바르지 않습니다!")
} else {
setEmailError("")
}
if(password !== passwordCheck){
setPasswordError("비밀번호가 일치하지 않습니다!")
} else {
setPasswordError("")
}
}
return (
<Wrapper>
<Title>코드캠프 회원가입</Title>
이메일: <input type="text" onChange={onChangeEmail} /><br />
<Warn>{emailError}</Warn>
비밀번호: <input type="password" onChange={onChangePassword} /><br />
비밀번호 확인: <input type="password" onChange={onChangePasswordCheck} /><br />
<Warn>{passwordError}</Warn>
<button onClick={onClickSignup}>회원가입</button>
</Wrapper>
)
}
これはuseStateの練習の課題です.useStateとonChange={}は、event関数を初めて使うのですが、初めてなので見慣れないし、難しいです.
これは私が初めて関数を使ったのですが、どこがどのように働いているのか分からないので、私はもがいて疲れていたのを覚えています.
この日も同僚に助けを求め、構造を理解しようとした.
私を助けてくれた同僚に无限の感谢を表します.本当にありがとう!
本課題は以下のとおりである.
登録ボタンをクリックし、条件文を使用してエラーを検証します.
*条件1)電子メールに@がない場合はエラーです.
*条件2)パスワードと確認パスワードが異なる場合はエラーとなります.
*条件3)エラーのない入力に対応した状態でエラーが削除されます(Null値に変更されます).
エラーを赤の入力ボックスの下部にマークしてください.
これらの条件を満たすべきだったのですが、
条件3をどのように実現しますか?ずっと悩んでいる.
これも他の同僚の一言で解決した.
他の人に比べて、彼はまだ知識に乏しく、一人で問題を解決するのに困難に直面しているようだ.
しかし、一つを理解するたびに、進歩を感じます.
練習Day 3/GRAPHQL
Code campが提供するAPIを用いて変異とqueryを練習した.
https://canyon-buffer-0c2.notion.site/example-1-GRAPHQL-313289352d1b46c081b6f36a065f053b
https://canyon-buffer-0c2.notion.site/backend03-2-GRAPHQL-723400a0f90949fdacf5479eea00ecac
Day 4 / REST-API, GRAPHQL-API
リクエストREST-API
import axios from 'axios'
import { useState } from 'react'
export default function RestGetPage(){
const [data, setData] = useState("")
const callRestApi = async () => {
const result = await axios.get("https://koreanjson.com/users")
//get=메서드 endpoint= users
console.log(result)
console.log(result.data.title)
setData(result.data.title)
}
return (
<div>
<div>{data}</div>
<button onClick={callRestApi}>REST-API 요청하기</button>
</div>
)
}
Rest-APIリクエストボタンを作成し、このボタンをクリックすると、get方式でhttps://koreanjson.com/usersというEndpointにリクエストしてデータを受信します.GRAPHQL-APIリクエスト
//import axios from "axios";
import { useState } from "react";
import { useMutation, gql } from "@apollo/client";
const CREATE_PRODUCT = gql`
mutation createProduct(
$seller: String
$createProductInput: CreateProductInput!
) {
createProduct(seller: $seller, createProductInput: $createProductInput) {
_id
number
message
}
}
`;
export default function GraphqlMutationProduct() {
const [seller, setSeller] = useState("")
const [product, setProduct] = useState("")
const [contents, setMyContents] = useState("")
const [price, setPrice] = useState("")
const [data, setData] = useState("")
const [createProduct] = useMutation(CREATE_PRODUCT);
const onClickSubmit = async () => {
const result = await createProduct({
variables: { seller: seller, createProductInput: {
//객체로 묶어 실행
name: product,
detail: contents,
price: price,
},
},
});
console.log(result);
console.log(result.data.createProduct.message);
setData(result.data.createProduct.message);
};
const onChangeSeller = (event) => {
setSeller(event.target.value)
}
const onChangeProduct = (event) => {
setProduct(event.target.value)
}
const onChangeContents = (event) => {
setMyContents(event.target.value)
}
const onChangePrice = (event) => {
setPrice(Number(event.target.value))
// Number는 숫자만 인식하므로 ParseInt(Int형으로 강제형변환)을 쓸 수도 있음
}
return (
<>
판매자: <input type="text" onChange={onChangeSeller}/>
<br />
상품명: <input type="text" onChange={onChangeProduct}/>
<br />
상품내용: <input type="text" onChange={onChangeContents}/>
<br />
상품가격: <input type="number" onChange={onChangePrice}/>
<br />
<button onClick={onClickSubmit}>상품 등록하기</button>
</>
);
}
作成者、タイトル、コンテンツに対してそれぞれ入力ラベルとステータスを作成し、直接入力した作成者、タイトル、コンテンツを変異させる必要があります.REST−APIはすべてのバックエンド値を受信することができ、GRAPHQL−APIは必要な値しか受信できないため、GRAPHQL−APIはコードを記述する際にさらに困難になる.
APIサーバをよくチェックし、新しい学習のgql、variables、async&awaitを復習します.
GRAPHQL-APIでは、常に価格値が受け取れないエラーが発生しました.
この問題はsetPrice(event.target.value)をsetPrice(number(event.target.value)に変更して解決しました.
コードレビューの授業で、もう一人の同僚がParseIntetが使えると言っていたので、私はまた少し勉強しました.
Day 5/動的ルーティングとデータ照会
商品登録画面の作成
// import axios from 'axios'
import { useMutation, gql } from "@apollo/client";
import { useRouter } from "next/router";
import { useState } from "react";
const CREATE_PRODUCT = gql`
mutation createProduct($seller: String, $createProductInput: CreateProductInput!) {
createProduct(seller: $seller, createProductInput: $createProductInput) {
_id
number
message
}
}
`;
export default function GraphqlMutationPage() {
const router = useRouter();
const [seller, setSeller] = useState("");
const [name, setName] = useState("");
const [detail, setDetail] = useState("");
const [price, setPrice] = useState("");
const [callApi] = useMutation(CREATE_PRODUCT);
const callGraphqlApi = async () => {
// const result = await axios.get("https://koreanjson.com/posts/1") // rest-api 방식
try {
const result = await callApi({
variables: { seller: seller, createProductInput:{
name: name,
detail : detail,
price : price
} },
}); // graphql-api방식
console.log(result);
console.log(result.data.createProduct.message);
alert("게시글 등록에 성공했어요");
alert("상세 페이지로 이동해 볼까요?");
router.push(
// ↓주소 틀렸었음
`/quiz/05-02/${result.data.createProduct._id}`
);
} catch (error) {
alert(error.message);
}
};
const onChangeSeller = (event) => {
setSeller(event.target.value);
};
const onChangeName = (event) => {
setName(event.target.value);
}
const onChangeDetail = (event) => {
setDetail(event.target.value);
};
const onChangePrice = (event) => {
setPrice(Number(event.target.value));
};
return (
<div>
{/* <div>{data}</div> */}
판매자: <input type="text" onChange={onChangeSeller} /> <br />
상품명: <input type="text" onChange={onChangeName} /> <br />
상품내용: <input type="text" onChange={onChangeDetail} /> <br />
상품가격: <input type="number" onChange={onChangePrice} /> <br />
<button onClick={callGraphqlApi}>상품 등록</button>
</div>
);
}
毎日勉強したことを身につけるのに忙しくて、気づかなかったので、振り返ると、毎日の勉強が少しずつ増えているような気がして、ページができました.不思議ですね.5日目はtry~catch文とルータを使って、他のページに移動できます.
5日間勉強したものの中で、ルーターが一番面白いです.今は自分で何かを実行する実感が...
gqlを用いて所望のデータを取得し,UserMutationを用いて商品を登録し,UserRouterを用いてデータをプッシュする.
import { useQuery, gql } from "@apollo/client";
import { useRouter } from "next/router";
const FETCH_PRODUCT = gql`
query fetchProduct($productId: ID) {
fetchProduct(productId: $productId) {
_id
seller
name
detail
price
}
}
`;
export default function DynamicRoutedPage() {
const router = useRouter()
console.log(router)
const { data } = useQuery(FETCH_PRODUCT, { //요청이 날아감(비어있는 상태 undefined)
variables: { productId: router.query.ProductId }
// ↑ gql에서 지정하는 값
})
console.log(data)
return(
<div>
<div>{data?.fetchProduct._id} 게시글에 오신 것을 환영합니다</div>
<div>판매자: {data? data.fetchProduct.seller : "loading..." }</div>
<div>상품명: {data? data.fetchProduct.name : "loading..." }</div>
<div>상품내용: {data? data.fetchProduct.detail : "loading..." }</div>
<div>상품가격: {data? data.fetchProduct.price : "loading..." }</div>
{/* 조건부 렌더링: 데이터가 있으면 뒤에꺼(데이터) 보여줘 없으면 앞에꺼(작성자..) 보여줘 */}
{/* // data && data.fetchBoard.number = data?.fetchBoard.number
Optional-Chaining이라고 한다. */}
</div>
)
}
pushのデータはこちらに飛んでページを印刷します.variables:{ProductId:route.query.ProductId}前のProductIdと後のProductIdをかなり混同しています.前はgqlで設定した値で、ProductIdは私が設定した動的ルーティングフォルダの名前です.
動的ルーティングフォルダ名には、四角カッコを使用する必要があります.
最后に入力したのはすべて适切なようで、しかしルートはよくなくて、だから同僚に助けを求めて、结果はrouterを発见します.Pushパスが間違っています.
Week 1ポートフォリオ
1週間の学習内容に基づいて、すべてを適用して掲示板登録ページと詳細ページを実現した.
作成者とパスワード、タイトル、コンテンツを入力します.
投稿登録に成功したことをalertで通知します.
作成ページに入力した値を詳細ページにインポートしました.
残りはcssから作るのでゆっくりと作ります.
ブログを書いていて何も知らなかった先週に比べて、ずいぶん進歩しました.
困难でもあきらめず、毎日芝生を作って顽张りましょう.
^-----^
Reference
この問題について(Week 1レビュー), 我々は、より多くの情報をここで見つけました https://velog.io/@hhjk00/Week-1-회고テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol