-
Notifications
You must be signed in to change notification settings - Fork 20
[황혜진] sprint6 #68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[황혜진] sprint6 #68
The head ref may contain hidden characters: "React-\uD669\uD61C\uC9C4-sprint6"
Conversation
|
스프리트 미션 하시느라 수고 많으셨어요. |
mission5 브렌치에서 mission6 작업을 진행하여 reset soft를 사용해서 새로운 mission6 브렌치에 하나의 커밋으로 푸쉬하였습니다 😓넵넵 ! 😊 참고하겠습니다 ! |
| #환경변수 무시 | ||
| .env |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
크으 ~ 굿굿 👍
환경변수를 만들고 gitignore에 추가하셨군요 ! 😊
피드백 반영 넘 좋습니당
| try { | ||
| const response = await axios.get(`${BASE_URL}/products`, { | ||
| params: { page, pageSize, orderBy, keyword }, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
axios를 적용해보셨군요 ! 👍
ㅠㅠㅠ 피드백 수용을 넘 잘하세요 👍 좋은 경험이 될거라 생각해요.
다만, 하나 더 제안드리고 싶은건 instance를 생성하고 적용해볼 수 있어요:
어떻게 세팅하면 될까? 🤔
instance를 만들어서 export를 하고 사용해보는 것 정도로 시도해보면 좋을 것 같아요. axios-instance 파일을 만들어서 instance를 생성하고 export한 후 사용해보는건 어떨까요?
다음과 같이 만들어볼 수 있어요:
const baseURL = process.env.NEXT_PUBLIC_LINKBRARY_BaseURL;
const instance = axios.create({
baseURL: baseURL,
headers: {
'Content-Type': 'application/json',
},
});
export default instance인가에 필요한 accessToken을 localStorage가 있다면 axios의 인터셉터를 활용할 수 있습니다 !
인터셉터는 혼자 해결해보시는 것을 권장드립니다. 혹시 모르시겠으면 다음 위클리 미션에 질문해주세요. 😊
사용 방법 🚀
사용 방법은 정말 간단해요. 다음과 같이 사용할 수 있습니다:
instance.get(`/user/${userId}`)딱 보니. 마이그레이션도 정말 쉽게 할 수 있겠죠? 😊
| queryParams.append("keyword", keyword); | ||
| return response.data; | ||
| } catch (error) { | ||
| throw new Error(`HTTP error: ${error.response?.status || error.message}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(제안) error.message를 먼저 반환시키는건 어떨까요?
| throw new Error(`HTTP error: ${error.response?.status || error.message}`); | |
| throw new Error(`HTTP error: ${error.response?.message || error.status}`); |
message에 서버로부터의 에러가 포함되어있을 수 있을 것 같아요.
만약 서버 에러 메시지가 포함되어있다면 유저에게 노출할 수도 있겠구요 !
상태만 반환하게 된다면 어떤 에러인지 유저, 그리고 컴포넌트에서도 파악하기 어려울 수 있겠죠?:
example:
400상태만 가지고는 이메일 형식 불일치인지, 빈 값인지 알 수 없을거예요.
| export default function ImageUploader() { | ||
| const [previewImage, setPreviewimage] = useState(null); | ||
| const [showLimitText, setShowLimitText] = useState(false); | ||
|
|
||
| const handleImageChange = (e) => { | ||
| const file = e.target.files[0]; | ||
| if (file) { | ||
| const imageUrl = URL.createObjectURL(file); | ||
| setPreviewimage(imageUrl); | ||
| setShowLimitText(false); // 새로 업로드 성공했으니 문구 지우기 | ||
| } | ||
| }; | ||
|
|
||
| const handleRemoveImage = () => { | ||
| setPreviewimage(null); | ||
| setShowLimitText(false); // 이미지 삭제했으니 문구 지우기 | ||
| }; | ||
|
|
||
| const handleUploadClick = (e) => { | ||
| if (previewImage) { | ||
| e.preventDefault(); | ||
| setShowLimitText(true); // 문구 보여주기 | ||
| } | ||
| }; | ||
|
|
||
| const isImageUploaded = !!previewImage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굿굿 ! 컴포넌트가 참 깔끔한데요? 💯
| const updatedTags = [...tags, inputValue.trim()]; | ||
| setTags(updatedTags); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굿굿 ! 배열을 새로 만들어서 상태를 변경하셨군요 ! 👍
배열의 경우 요소를 추가/삭제 하는 것이 아닌 새로운 주소의 배열로 변경을 해줘야하지요. 훌륭합니다 😊
| setTags(updatedTags); | ||
| onChange(updatedTags); | ||
| } | ||
| setTimeout(() => setInputValue(""), 0); // 입력 후 초기화 + 엔터 눌렀을 때 새로고침 방지 비동기처리 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setTimeout를 없애도 되지 않을까요? 🤔
| setTimeout(() => setInputValue(""), 0); // 입력 후 초기화 + 엔터 눌렀을 때 새로고침 방지 비동기처리 | |
| setInputValue("") |
| const maxItems = | ||
| window.innerWidth <= BREAKPOINTS.MOBILE | ||
| ? size === "large " | ||
| ? 1 | ||
| : 4 | ||
| : window.innerWidth <= BREAKPOINTS.TABLET | ||
| ? size === "large" | ||
| ? 2 | ||
| : 6 | ||
| : window.innerWidth <= BREAKPOINTS.LAPTOP | ||
| ? size === "large" | ||
| ? 3 | ||
| : 8 | ||
| : size === "large" | ||
| ? 4 | ||
| : 10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
삼항 연산자가 많아지면 가독성이 떨어질 수 있지욤.
다음과 같이 정의하고 사용해볼 수 있을 것 같아요 !:
const breakpoints = [
{ maxWidth: BREAKPOINTS.MOBILE, values: { large: 1, default: 4 } },
{ maxWidth: BREAKPOINTS.TABLET, values: { large: 2, default: 6 } },
{ maxWidth: BREAKPOINTS.LAPTOP, values: { large: 3, default: 8 } },
];위와 같이 정의해두고 필요한 값을 찾아볼 수 있어요:
const matchedBreakpoint =
breakpoints.find((bp) => window.innerWidth <= bp.maxWidth) || {
values: { large: 4, default: 10 },
};
const maxItems = matchedBreakpoint.values[size === "large" ? "large" : "default"];마찬가지로 if가 많아지거나 조건이 많이 붙는다면 객체 혹은 배열로 정의하고 find나 키로 접근하여 가독성 및 유지보수성을 좋게 만들어볼 수 있습니다 ! 😊
|
수고하셨습니다 혜진님 ! 이번에도 정말 수고 많으셨습니다 혜진님 ! 👍👍 |
요구사항
기본
심화
주요 변경사항
스크린샷
멘토에게