import { Input, Button} from 'antd'; const { TextArea } = Input; import { useState } from "react";// 저장하는 곳임포트 const DiaryInput = ({ isLoading, onSubmit }) => { const [userInput, setUserInput] = useState(""); // isLoading 로딩상태에서 사용하는 변수 // inSubmit 다입력 작성하면 사용 const handleUserInput = (e) => { setUserInput(e.target.value); }; const handleClick = () => { onSubmit(userInput); }; return ( <div> <TextArea value={userInput} onChange={handleUserInput} placeholder="오늘 일어난 일들을 간단히 적어주세요." /> <Button loading={isLoading} onClick={handleClick}> GPT 회고록을 작성해줘! </Button> </div> ); } export default DiaryInput; // import { Input , Button} from 'antd'; // import { useState } from 'react'; // const { TextArea } = Input; // const DiaryInput = ({isLoading, onSubmit}) => { // const [userInput, setUserInput] = useState(""); // //사용자의 입력을 받아 상위 컴포넌트로 넘기기 // // 로딩상태에서는 제출버튼 못누루게 // const handleUserInput =(e)=>{ // setUserInput(e.target.value); // const handleClick = ()=>{ // onSubmit(userInput); // } // } // return ( // <div> // <TextArea value={userInput} onChange={handleUserInput} placeholder='오늘 하루 회고'/> // <Button loading={isLoading} onClick={handleClick}>GPT회고록 시작</Button> // </div> // ); // }; // export default DiaryInput; import { useState } from 'react'; import { CallGPT } from './api/gpt'; import DiaryInput from './components/DiaryInput'; const dummyData = { "title": "고립된 개발자의 고민", "thumbnail": "https://source.unsplash.com/1600x900/?programming", "summary": "혼자 코딩과제를 진행하면서 걱정이다.", "emotional_content": "최근 혼자 코딩과제를 진행하면서, 협업이 없이 모든 것을 혼자 결정하고 해결해야 한다는 부담감에 많이 무겁습니다. 강의를 듣고 최선을 다해 프로젝트를 진행했지만, 예상치 못한 버그들로 인해 스트레스가 많이 쌓였습니다. 스택오버플로와 GPT를 통해 문제를 해결하긴 했지만, 이러한 문제해결 방식이 정말로 제 개발 실력을 향상시키는지에 대해 의문이 듭니다. 왠지 스스로의 능력을 시험할 기회를 잃은 것 같아 아쉽고, 불안감도 커지고 있습니다.", "emotional_result": "이 일기에서 감지되는 감정은 불안, 부담감, 그리고 자신감의 결여입니다. 고립된 상황에서의 성공에 대한 압박감과 문제 해결 방법에 대한 의심은 정서적으로 큰 부담을 주고 있습니다. 자기 효능감이 낮아짐을 느끼는 상황입니다.", "analysis": "고립되어 문제를 해결하는 과정은 큰 스트레스와 불안을 유발할 수 있습니다. '혼자서 하는 일은 좋은 일이든 나쁜 일이든 더욱 크게 느껴진다'는 에릭 에릭슨의 말처럼, 혼자서 모든 것을 해결하려는 시도는 때로는 개인의 성장에 도움이 될 수 있지만, 지속적인 고립은 자기 효능감을 저하시킬 수 있습니다. 이러한 상황에서는 자신의 노력을 인정하고, 필요한 경우 도움을 요청하는 것이 중요합니다.", "action_list": [ "프로젝트 중 발생하는 문제를 혼자 해결하려 하지 말고, 멘토나 동료 개발자와 상의를 통해 해결 방안을 모색하라.", "정기적으로 자신의 학습 방법과 진행 상황을 평가하여, 필요한 경우 학습 방식을 조정하라.", "개발 과정에서의 스트레스 관리를 위해 적절한 휴식과 여가 활동을 통해 정서적 안정을 찾으라." ] }; function App() { const [data, setData] = useState(dummyData); // 우선 빈문자열로 해놓고 const [isLoading, setIsLoading] = useState(false); const handleClickAPICall = async (userInput) => { try { setIsLoading(true);// 처음에는 로딩을 트루 const message = await CallGPT({ prompt: `${userInput}`, }); // Assuming callGPT is a function that fetches data from GPT API setData(JSON.parse(message)); } catch (error) { // Handle error (you might want to set some error state here) } finally { setIsLoading(false);//다음에는 펄스로 } }; const handleSubmit = (userInput) => { handleClickAPICall(userInput); }; console.log(">>data", data); return ( <> <DiaryInput isLoading={isLoading} onSubmit ={handleSubmit} /> <button onClick={handleClickAPICall}>GPT API call</button> <div>title : {data?.title}</div> <div>analysis : {data?.analysis}</div> <div>emotional_content : {data?.emotional_content}</div> <div>emotional_result : {data?.emotional_result}</div> </> ); }; export default App; // import { useState } from "react"; // import { CallGPT } from "./api/gpt"; // import { message } from "antd"; // import DiaryInput from "./components/DiaryInput"; // const dumyData = JSON.parse(` // { // "title": "당황스러운 예제 에러", // "thumbnail": "https://source.unsplash.com/1600x900/?confused", // "summary": "가끔 예제 에러가 발생하여 당황함", // "emotional_content": "가끔 예제 에러가 나타나는 것이 정말 당황스럽다. 이런 상황들은 예상치 못한 문제로 인해 나를 혼란스럽게 만든다. 그럼에도 불구하고, 이런 에러들은 동시에 나의 문제 해결 능력을 시험한다.", // "emotional_result": "당황스러움과 혼란스러움이 느껴진다. 그러나 이는 예상치 못한 문제에 대처하는 능력을 향상시키는 과정일 수 있다.", // "analysis": "당신의 당황함과 혼란스러움은 예상치 못한 상황에 대한 불안감과 두려움을 반영할 수 있습니다. 하지만, '문제는 기회다'라는 유명한 격언을 기억하십시오. 이러한 에러들은 당신의 문제 해결 능력을 향상시키는 좋은 기회일 수 있습니다.", // "action_list": [ // "예상치 못한 에러에 대비하는 습관 만들기", // "문제 해결 능력 향상을 위한 자기계발", // "당황하지 않고 차분하게 상황을 평가하는 능력 기르기" // ] // } // `); // function App() { // const [data, setData] = useState(dumyData); // const [isLoading, setIsLoading] = useState(false); // // 여기로딩상태가 // const handleClickAPICall = async (userInput) => { // try{// try catch로 감싸서, 처음에는 로딩상태를 트루라고 하고 // setIsLoading(true); // const message = await CallGPT({ // prompt:'{userInput}', // }); // setData(JSON.parse(message));// 그리고 데이터가 잘오면 받아보자 // } catch (error){ // }finally{ // setIsLoading(false);// 나중에는 false라고 하자 // } // }; // const handleSubmit = (userInput)=>{ // handleClickAPICall(userInput); // }; // console.log(">>data", data); // return ( // <> // <DiaryInput isLoading={isLoading} onSubmit={handleSubmit} /> // // 여기로 옴 // <button onClick={handleClickAPICall}>GPT API call</button> // <div>data : {data?.title}</div> // <div>thumbnail: {data?.thumbnail}</div> // <div>summary : {data?.summary}</div> // <div>emotional_resul : {data?.emotional_resul}</div> // <div>emotional_content : {data?.emotional_content}</div> // <div>analysis: {data?.analysis}</div> // <div>action_list: {data?.action_list}</div> // </> // ); // } // export default App ;{ "name": "my-gpt-diary", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, "dependencies": { "@ant-design/icons": "^5.4.0", "antd": "^5.20.1", "react": "^18.3.1", "react-dom": "^18.3.1", "styled-components": "^6.1.12" }, "devDependencies": { "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "typescript": "^5.2.2", "vite": "^5.3.4" } }
이게 계속로딩중이라고 뜹니다 import { Input, Button} from 'antd'; const { TextArea } = Input; import { useState } from "react";// 저장하는 곳임포트 const DiaryInput = (isLoading, onSubmit) => { const [userInput, setUserInput] = useState(""); // isLoading 로딩상태에서 사용하는 변수 // inSubmit 다입력 작성하면 사용 const handleUserInput = (e) => { setUserInput(e.target.value); }; const handleClick = () => { onSubmit(userInput); }; return ( <div> <TextArea value={userInput} onChange={handleUserInput} placeholder="오늘 일어난 일들을 간단히 적어주세요." /> <Button loading={isLoading} onClick={handleClick}> GPT 회고록을 작성해줘! </Button> </div> ); } export default DiaryInput; import { useState } from 'react'; import { CallGPT } from './api/gpt'; import DiaryInput from './components/DiaryInput'; const dummyData = { "title": "고립된 개발자의 고민", "thumbnail": "https://source.unsplash.com/1600x900/?programming", "summary": "혼자 코딩과제를 진행하면서 걱정이다.", "emotional_content": "최근 혼자 코딩과제를 진행하면서, 협업이 없이 모든 것을 혼자 결정하고 해결해야 한다는 부담감에 많이 무겁습니다. 강의를 듣고 최선을 다해 프로젝트를 진행했지만, 예상치 못한 버그들로 인해 스트레스가 많이 쌓였습니다. 스택오버플로와 GPT를 통해 문제를 해결하긴 했지만, 이러한 문제해결 방식이 정말로 제 개발 실력을 향상시키는지에 대해 의문이 듭니다. 왠지 스스로의 능력을 시험할 기회를 잃은 것 같아 아쉽고, 불안감도 커지고 있습니다.", "emotional_result": "이 일기에서 감지되는 감정은 불안, 부담감, 그리고 자신감의 결여입니다. 고립된 상황에서의 성공에 대한 압박감과 문제 해결 방법에 대한 의심은 정서적으로 큰 부담을 주고 있습니다. 자기 효능감이 낮아짐을 느끼는 상황입니다.", "analysis": "고립되어 문제를 해결하는 과정은 큰 스트레스와 불안을 유발할 수 있습니다. '혼자서 하는 일은 좋은 일이든 나쁜 일이든 더욱 크게 느껴진다'는 에릭 에릭슨의 말처럼, 혼자서 모든 것을 해결하려는 시도는 때로는 개인의 성장에 도움이 될 수 있지만, 지속적인 고립은 자기 효능감을 저하시킬 수 있습니다. 이러한 상황에서는 자신의 노력을 인정하고, 필요한 경우 도움을 요청하는 것이 중요합니다.", "action_list": [ "프로젝트 중 발생하는 문제를 혼자 해결하려 하지 말고, 멘토나 동료 개발자와 상의를 통해 해결 방안을 모색하라.", "정기적으로 자신의 학습 방법과 진행 상황을 평가하여, 필요한 경우 학습 방식을 조정하라.", "개발 과정에서의 스트레스 관리를 위해 적절한 휴식과 여가 활동을 통해 정서적 안정을 찾으라." ] }; function App() { const [data, setData] = useState(dummyData); // 우선 빈문자열로 해놓고 const [isLoading, setIsLoading] = useState(false); const handleClickAPICall = async (userInput) => { try { setIsLoading(true);// 처음에는 로딩을 트루 const message = await CallGPT({ prompt: `${userInput}`, }); // Assuming callGPT is a function that fetches data from GPT API setData(JSON.parse(message)); } catch (error) { // Handle error (you might want to set some error state here) } finally { setIsLoading(false);//다음에는 펄스로 } }; const handleSubmit = (userInput) => { handleClickAPICall(userInput); }; console.log(">>data", data); return ( <> <DiaryInput isLoading={isLoading} onSubmit ={handleSubmit} /> <button onClick={handleClickAPICall}>GPT API call</button> <div>title : {data?.title}</div> <div>analysis : {data?.analysis}</div> <div>emotional_content : {data?.emotional_content}</div> <div>emotional_result : {data?.emotional_result}</div> </> ); }; export default App;
■ 질문 남기실 때 꼭! 참고해주세요. - 먼저 유사한 질문이 있었는지 검색해주세요. - 궁금한 부분이 있으시면 해당 강의의 타임라인 부분을 표시해주시면 좋습니다. - HTML, CSS, JQUERY 코드 소스를 텍스트 형태로 첨부해주시고 스크린샷도 첨부해주세요. - 다운로드가 필요한 파일은 해당 강의의 마지막 섹션에 모두 있습니다. 질문 하실 때 어떤 유형인지 말씀해주세요. ex) 완성본만 있구 와이어프레임만있는 html파일은 어딨나요 ?
각 타입별 이미지 크기 제작할 때 가. A,B타입 (width: 1200px, height: 300px) 나. C타입 (width: 800px, height: 350px) 로 제작하면 되는데 D,E,F유형에는 100%로 구성되어있는데 전체 몇 px로 구성해서 만들면되는지 궁금합니다. 주조색&보조색의 의미가 궁금합니다...
■ 질문 남기실 때 꼭! 참고해주세요. - 먼저 유사한 질문이 있었는지 검색해주세요. - 궁금한 부분이 있으시면 해당 강의의 타임라인 부분을 표시해주시면 좋습니다. - HTML, CSS, JQUERY 코드 소스를 텍스트 형태로 첨부해주시고 스크린샷도 첨부해주세요. - 다운로드가 필요한 파일은 해당 강의의 마지막 섹션에 모두 있습니다. 질문 하실 때 어떤 유형인지 말씀해주세요. ex) A1 작업하는데 ???이 안됩니다 감점사항인가요 ? 이런것두 ?
안녕하세요. 현재 강의 중 프로젝트 1 단계를 진행중에 궁금점이 생겨 질문 드립니다. index.html 파일 디자인에 부트스트랩 만으로 작업 하지 않고 순수 css 를 함께 이용하시는데요. 분류 원칙이 따로 있으신가요? 예를 들면 section 요소에 배경이미지는 *. css 파일에 position : relative, position : absolute 처리도 *.css 에서 처리를 하시네요.
안녕하세요. 소플님. Custom Hook에 대해서 질문이 있어 글을 남깁니다. import {useState, useEffect} from 'react'; // 커스텀 훅 function useUserStatus(userId){ const [isOnline, setIsOnline] = useState(null); useEffect(() =>{ function handleStatusChange(status){ setIsOnline(status.isOnline); } ServerAPI.subscribeUserStatus(userId, handleStatusChange); return () =>{ ServerAPI.unsubscribeUserStatus(userId, handleStatusChange); } }); return isOnline; } function UserStatus(props){ // 중복된 로직을 custom hook으로 추출하고 호출하여 간편하게 사용 const isOnline = useUserStatus(props.user.id); if (isOnline == null) return "대기중..."; return isOnline ? '온라인' : '오프라인'; } function UserListItems(props){ // 중복된 로직을 custom hook으로 추출하고 호출하여 간편하게 사용 const isOnline = useUserStatus(props.user.id); return ( <li style={{color: isOnline ? 'green':'black'}} > {props.user.name} </li> ); } 위 방식은 강의 내용대로 중복된 로직을 추출하여 Custom Hook을 만들고 함수 컴포넌트 내에서 호출하여 사용하는 방식입니다. 강의 내에서 " 여러 개의 컴포넌트에서 하나의 공통된 Custom Hook을 사용할 때 컴포넌트 내부에 있는 모든 state와 effects는 전부 분리되어 있다." 라고 말씀하셨는데 Custom Hook도 본질은 JS함수이기에 함수의 선언의 parameter와 사용의 argument는 다른 것과 같기 때문으로 이해해도 될까요? 좋은 리액트 강의 감사합니다. 꼭 완강하겠습니다!
지금 카드를 3d로 뒤집는데 그냥 뒤집히는게아니라 카드의 뒷면이 무엇인지 왼쪽아래나 왼쪽면부터 조금씩 뒤집어지는 느낌으로 뒤집기 위해선 animation3에서 이미지를 나눠서 보여준것처럼 효과를 줘야할까요? 그냥 카드가 3d로 휙 뒤집히는게 아닌 책장넘길때처럼 구현하고싶은데 뒷면을 확인할때 긴장감을 주기위해서 혹시 어떤 방법이 있을까요?
폰트어썸으로 라디오버튼과 체크박스를 커스텀 하는 강의에서, checked 가상클래스는 input[type=checkbox] 에 적용하였으나 (체크박스를 누르는 것이므로 active 또한 input[type=checkbox]에 적용하면 자연스럽다고 생각하여서)active는 label에 적용한 이유를 모르겠습니다.