klmhyeonwooo
2022.02.24
@klmhyeonwooo님이
모각코 리액트, 14화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.24
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 14화
금일 포스팅 내용은 시간 가공 함수인 Moment에 관련된 내용으로 포스팅을 하려고 합니다. 변수를 지정하여, 시간과 시간 값의 차이를 나타내는 부분을 손 쉽게 Moment를 통해 나타내줄 수 있는데, 자바스크립트에서 제공하는 기본적인 시간 계산 Date 객체와는 달리 사용면에서 상당한 편의성을 제공합니다. 다른 리액트 라이브러리와 동일하게 import를 통해 라이브러리를 불러올 수 있으며, 하단의 import 'moment/locale/ko'; 을 통해 시간의 차이를 한글로 출력을 해줄 수 있습니다. import 'moment/locale/ko'; import moment from 'moment'; 이번 14日에서 주요하게 보았던 점은 다음과 같습니다. 작은 따옴표와 백틱의 차이 toFixed 함수를 통해 인자로 받은 정수 값 아래에서 반올림 Moment의 기본 문법 구조 먼저 처음에는 백틱에 대한 구조를 잘 몰랐습니다, JSX 문법을 검색해도 백틱에 대한 정의가 나와있지 않아서 "?" 라는 물음만 계속 제기하던 중, 애초에 한국어 사용자는 한국어 표기 시 사용할 일이 없는 기호 보통 특정 발음기호를 가진 알파벳을 나타낼 때 씁니다. 주로 말을 생략하거나 소유격을 쓸 때 사용하는 아포스트로피나 주로 인용 문구를 담을 때 쓰는 따옴표와는 다르다. 벨로그를 포함해 마크다운(markdown)언어에서 1개 ~ 3개 기호 개수에 따라 inline 속성 또는 block 속성으로 코드블록을 입력할 때 쓰이기도 함 참고로, Ruby, PHP 등 언어에서 명령 대체 문법으로 사용되기도 한다고 합니다. 루비에서 배쉬창을 이용하여 scaffold 관련 개발만 하다보니까, 백틱에 관련된 부분은 몇번 보았지만 개념을 잊어먹은 것 같았다. 맥에서는 "option + ~" 에 대한 커맨드 입력을 통해 백틱을 입력할 수 있습니다. toFixed 함수는 이번 14日에서 사용하였던 내부 코드와 함께 설명을 할 수 있는데, else if (viewCount < 10000) { return `조회수 ${(viewCount / 1000).toFixed(1)}천회`; viewCount가 10000 아래일 경우, viewCount를 1000으로 나누고 첫번째 소숫점 아래에서 반올림을 해주고 리턴을 해주는 함수입니다. 그러니까 9750회일 경우, 1000으로 나눈 값은 9.75, 첫번째 소숫점 아래에서 반올림을 해주면 9.8천회가 됩니다. Moment의 기본 문법 구조는 다음과 같습니다. moment().from(Moment|String|Number|Date|Array); moment().from(Moment|String|Number|Date|Array, Boolean); 생각보다 간단하면서 생각보다 까다로운데, 데이터 값이 어떻게 흐르는 지를 보면 빠르게 이해가 가능한 라이브러리라고 생각이 듭니다. 오늘 구현한 코드들은 14日 설명에 대한 코드랑 별반 다르지 않은 코드이지만, 깃허브에 커밋을 해놓겠습니다 ;-) [사진 1, 프로그래밍 구현 결과]
kimbyunsoo
2022.02.23
@kimbyunsoo님이
모각코 리액트, 13화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.23
@klmhyeonwooo님이
모각코 리액트, 13화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.23
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 13화
금일 포스팅 내용은 카테고리에 따른 필터 분류 기능에 대한 내용으로 포스팅을 진행하려고 합니다. 모각코에서 제공하는 자료 오류로 인해, 13日과 12日이 변경되었습니다 12日에 따른 과제는 손쉽게 할 수 있었는데, 13日 과제는 조금 어렵게 다가왔던 것 같습니다. 컴포넌트도 다양하게 만들어야하고, 기능에 따른 useState를 어떤 방식으로 사용할 것인지에 대해서도 다양하며 새로운 방식으로 코딩에 임해야한다는 것을 새삼 한번 더 알게 되었습니다. 이번 코드에서 주요하게 동작하는 함수와 컴포넌트는 다음과 같습니다. mapFunc(data, index) : 배열인 데이터들을 인덱스와 함께 정렬 시키지만, 내부 프로그램에서는 HomeFilter 컴포넌트와 함께 사용을 하여 데이터를 넘겨주며 클릭 이벤트를 발생시킴 (클릭 이벤트에서는 클릭된 데이터를 필터 데이터로 저장) filterFunc(data) : 데이터의 일정 요소들을 필터링 해주는 함수, 내부 프로그램에서는 필터 값이 전체 또는 일정 값에 대한 데이터 속성을 가지고 있다면 true 값을 리턴시켜주면서 관련된 내용을 HomeCard component를 통해 데이터를 불러올 수 있음 HomeCard component : 데이터를 받아서 데이터 안의 속성들을 이용하여 유튜브의 영상 카드들을 출력해주는 컴포넌트 Homefilter component : text 안에 주입된 data 값과 클릭 이벤트로 발생된 필터의 값이 같으면 UI 스타일을 검정색으로 변경 및 활성화 function Home() {   const [filter, setFilter] = useState('전체');   function mapFunc(data, index) {     return (       <HomeFilter         filter={filter}         text={data}         onClickFilter={function () {           setFilter(data);         }}         key={`home-filter-${index}`}       />     );   }   function filterFunc(data) {     if (filter === '전체' || data.title.includes(filter)) {       return true;     }     else {     return false;     }     }   return (     <Layout activeMenu="home">       <div className={styles.header}>{target.map(mapFunc)}</div>       <div className={styles.container}>         <div className={styles.grid}>         {youtubeData['data'].filter(filterFunc).map(HomeCard)}</div>       </div>     </Layout>   ); } export default Home; [코드 1, Home.js] [사진 1, 프로그래밍 출력 결과 화면]
klmhyeonwooo
2022.02.23
@klmhyeonwooo님이
모각코 리액트, 12화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.22
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 12화
금일 포스팅 내용은 입력 창에 대한 렌더링에 관련된 내용으로 포스팅을 진행하려고 합니다. 모각코에서 제공하는 자료 오류로 인해, 13日과 12日이 변경되었습니다 사실 리액트 입문 전 구글링을 하다가, 리액트에서는 렌더링이 안된다는 이유로 INPUT에 대한 값들도 한번 입력을 해줄 때, onChange 메소드를 통해 최신화를 시켜줘야한다는 것을 알고있었습니다. 그래서 오늘 과제는 그래도 수월하게 했습니다만, 과제 오류로 인해 강제로 13화까지 듣게 되었네요, 13화가 생각보다 난이도가 있어서 조금 헤맸습니다. INPUT 창에 관련된 최신화 부분은 사실 긴 코드가 필요한 것이 아닌 onChange에 대한 함수 하나만을 기재하면 됩니다.   function onChange(event) {     setValue(event.target.value);   } [코드 1, onChange 메소드 함수] useState를 통해 기존 값에 추가로 덧붙여줌으로써, 값을 새롭게 저장해서 사용자에게 보여주는 방식입니다. //Header.js import React, {useState} from 'react'; import styles from './Header.module.css'; import youtube_logo from '../../images/youtube_logo.png'; import { FiMenu } from 'react-icons/fi'; import { IoSearchOutline } from 'react-icons/io5'; import { BsGrid3X3Gap } from 'react-icons/bs'; import { HiOutlineDotsVertical } from 'react-icons/hi'; function Header({changeState}) {   const [value, setValue] = useState("");   function onClick() {     alert("검색한 내용 : " + value);     setValue("");   }   function onChange(event) {     setValue(event.target.value);   }   return (     <div className={styles.header}>       <div className={styles.tab}>         <FiMenu className={styles.icon} onClick={changeState}/>         <img src={youtube_logo} alt="로고" className={styles.logo} />       </div>       <div className={styles['center-tab']}>         <input className={styles.input} value={value} onChange={onChange}/>         <IoSearchOutline className={styles['search-icon']} onClick={onClick}/>       </div>       <div className={styles.tab}>         <BsGrid3X3Gap className={styles.icon}/>         <HiOutlineDotsVertical className={styles.icon}/>       </div>     </div>   ); } export default Header; [코드 2, Header.js의 전체적인 코드] [사진 1, 프로그래밍 출력 화면]
klmhyeonwooo
2022.02.21
@klmhyeonwooo님이
모각코 리액트, 11화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.21
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 11화
금일 포스팅 내용은 저번 10日에 이어서, 메뉴 없애기에 관련된 포스팅으로 진행을 합니다. 저번 시간에는 단순히 햄버거 메뉴를 클릭하면 메뉴바가 사라지는 기능을 구현했다면, 이번 시간에는 햄버거 메뉴를 누르면 레이아웃까지 동시에 사라지면서, 충분한 공간효과를 제공해주는 기능을 구현하였습니다. 저번 시간과는 크게 코드에 대한 차이는 없지만 조건부 렌더링을 통해, 스타일 시트에 변화를 주는 형식으로 구현을 하였습니다. 점차 리액트에 익숙해지는 것 같으며, 컴포넌트 하나하나에 대한 개념들이 눈에 익는 것 같아서 기분이 좋네요 ;-) import styles from './Layout.module.css'; import Header from './Header'; import Menu from './Menu'; import React, { useState } from 'react'; function Layout({ children, activeMenu }) {   const [state, setState] = useState(true); //  function changeState() { //    if (state == true) { //      setState(false); //    } //    else { //      setState(true); //    } //  } // useState, useEffect는 항상 실행하는 순서가 동일해야함 // 조건문이나 반복문을 사용하면 실행순서가 바뀔 수 있어 예상치 못한 오류를 야기   function changeState() {     setState((state) => !state);   }   return (     <div className={styles.container}>       <Header changeState={changeState} />       <div className={styles.layout}>         <Menu activeMenu={activeMenu} statement={state}/>         <div className={state == true ? styles.contents : styles.contents_fold}>{children}</div>       </div>     </div>   ); } export default Layout; [코드 1, Layout.js] .container {   display: flex;   position: fixed;   top: 0;   left: 0;   right: 0;   bottom: 0;   overflow: overlay;   flex-direction: column;   /* border-color : red;   border-style: solid; */ } .layout {   display: flex;   flex: 1;   /* border-color : blue;   border-style: solid; */   margin-top : 56px; } .contents {   margin-left: 240px;   flex: 1; } .contents_fold {   margin-left: 0px;   flex : 1; } .menu {   display : none; } @media screen and (max-width:911px) {   .contents {     margin-left: 72px;   } } [코드 2, Layout.module.css] [사진 1, 프로그래밍 실행 결과]
klmhyeonwooo
2022.02.18
@klmhyeonwooo님이
모각코 리액트, 10화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.18
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 10화
금일 포스팅 내용은 햄버거바에 대한 ON/OFF 기능 구현에 대한 포스팅으로 다뤄보려고 합니다. 지금까지 컴포넌트 개념과 어느정도 리액트 동작방식에 대해서 조금씩 익숙해지는 것 같습니다. 그렇지만서도, useState를 통해 컴포넌트에서 데이터를 주고 받는 과정을 구현하는데는 시간을 아직은 많이 소모합니다. 앞으로 얼마남지 않은 리액트지만, 열심히해서 주언어로 만들어야겠습니다 ;-) import styles from './Layout.module.css'; import Header from './Header'; import Menu from './Menu'; import React, { useState } from 'react'; function Layout({ children, activeMenu }) {   const [state, setState] = useState(true); //  function changeState() { //    if (state == true) { //      setState(false); //    } //    else { //      setState(true); //    } //  }   function changeState() {     setState((state) => !state);     console.log(state);   }    // useState, useEffect는 항상 실행하는 순서가 동일해야하기 때문입니다. // 조건문이나 반복문을 사용하면 실행순서가 바뀔 수 있어 예상치 못한 오류를 야기하게 됩니다.   return (     <div className={styles.container}>       <Header changeState={changeState} />       <div className={styles.layout}>         <Menu activeMenu={activeMenu} statement={state}/>         <div className={styles.contents}>{children}</div>       </div>     </div>   ); } export default Layout; [코드 1, Layout.js] import styles from './Header.module.css'; import youtube_logo from '../../images/youtube_logo.png'; import { FiMenu } from 'react-icons/fi'; import { IoSearchOutline } from 'react-icons/io5'; import { BsGrid3X3Gap } from 'react-icons/bs'; import { HiOutlineDotsVertical } from 'react-icons/hi'; function Header({changeState}) {   return (     <div className={styles.header}>       <div className={styles.tab}>         <FiMenu className={styles.icon} onClick={changeState}/>         <img src={youtube_logo} alt="로고" className={styles.logo} />       </div>       <div className={styles['center-tab']}>         <input className={styles.input} />         <IoSearchOutline className={styles['search-icon']} />       </div>       <div className={styles.tab}>         <BsGrid3X3Gap className={styles.icon} />         <HiOutlineDotsVertical className={styles.icon} />       </div>     </div>   ); } export default Header; [코드 2, Header.js] import { Link } from 'react-router-dom'; import styles from './Menu.module.css'; import { TiHome } from 'react-icons/ti'; import { FaRegCompass } from 'react-icons/fa'; import { MdSubscriptions } from 'react-icons/md'; function Menu({ activeMenu, statement }) {   return (     <div className={styles.menu}>       { statement === true ?         <>       <Link         to="/"         className={activeMenu === 'home' ? styles.focused : styles.link}       >         <TiHome className={styles.icon} />홈       </Link>       <Link         to="/explore"         className={activeMenu === 'explore' ? styles.focused : styles.link}       >         <FaRegCompass className={styles.icon} />         탐색       </Link>       <Link         to="/subscription"         className={activeMenu === 'subscription' ? styles.focused : styles.link}       >         <MdSubscriptions className={styles.icon} />         구독       </Link>       </>     : null }     </div>   ); } export default Menu; [코드 3, Menu.js] [사진 1, 프로그래밍 실행 결과]
klmhyeonwooo
2022.02.16
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 8화
금일 포스팅 할 내용은 조건부 렌더링에 관련된 부분 중 삼항 연산자에 대해서 포스팅을 다뤄보려고 합니다. 삼항 연산자에 관련된 부분은 7화에서 구현했던 좋아요 기능에 메세지를 넣어, 사용자가 누른 좋아요 기능에 대한 활성 및 비활성 상태를 알려주는 시스템 메세지 기능을 구현해보려고 합니다. 삼항연산자는 세가지의 연산자를 사용하는 유일한 조건 연산자로써, 아래의 원리로 사용이 됩니다. 조건 ? 참이면 실행할 식 : 거짓이면 실행 할 식 조건에 따른 좋아요 버튼에 대한 구현은 다음과 같이 구현을 할 수 있습니다. 아래 첨부한 최상단의 코드는 저번 시간에 일반적으로 사용하는 조건부 렌더링에 관련된 부분으로 구현을 하였습니다. 그리고 하단에는 삼항연산자를 응용하여, 저번 시간에 작성하였던 코드를 변환하여 새롭게 코드에 첨부를 하였습니다. {value === false && <button type="submit"> <img src = {like} className={styles.false} onClick={onClick}/> </button> }     {value === true && <button type="submit"> <img src = {like} className={styles.true} onClick={onClick}/> </button>} {value ? <button type="image" className={styles.btn}> <img src = {like} className={styles.false} onClick={onClick}/> </button> : <button type="image" className={styles.btn}> <img src = {like} className={styles.true} onClick={onClick}/> </button>} 사용자에게 출력되는 시스템 메세지는 저번 시간에 배운 조건부 랜더링에 대한 조건으로 구현을 하였습니다. 사용자가 누른 좋아요에 관련된 시스템 메세지는 Boolean 값에 따라 긍정과 부정에 관련된 메세지를 출력해주기만 하면 됩니다, {value === false && <p className={styles.message}>좋아요가 비활성화되었습니다 ;-)</p>} {value === true && <p className={styles.message}>좋아요가 활성화되었습니다 ;-)</p>} 이렇게 코드를 작성해주면 다음과 같은 간단한 좋아요 기능과 시스템 메세지를 출력할 수 있게 됩니다.
klmhyeonwooo
2022.02.15
@klmhyeonwooo님이
모각코 리액트, 7화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.15
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 7화
금일 포스팅 내용은 조건부 렌더링에 관련된 내용으로 포스팅을 다뤄보려고 한다. 말 그대로, 조건에 따라 새롭게 렌더링을 시켜준다는 의미를 가지며, 리액트에서는 JSX를 사용할 때, 다음과 같이 사용을 할 수 있다. return ( ... { 조건 && 컴포넌트 } ... ); return ( <div> {true && <div>True일 때 출력되는 메세지</div>} {false && <div>False일 때 출력되는 메세지</div>} </div> ); 오늘은 이런 조건에 따른 렌더링 구조를 응용하여 '좋아요 기능' 을 구현하고자 하였다. 버튼 이미지 형태를 사용하였으며, 사용자가 버튼을 누르게 되면, 만들어놓은 이벤트 메소드와 함께 좋아요 이미지의 대한 변경이 이루어진다. import styles from './Button.module.css'; import like from './like.png'; function Button({value, onClick}) {   return (     <div>     {value === false && <button type="submit"> <img src = {like} className={styles.false} onClick={onClick}/> </button> }     {value === true && <button type="submit"> <img src = {like} className={styles.true} onClick={onClick}/> </button>}     </div>     ); } export default Button; App.js 에서는 다음과 같이 false에서 클릭했을 경우, true의 값으로 변환을 시켜주고, true의 경우 그 반대의 값으로 적용을 시켜준다.   function onClick() {     if (like_count == false) {       set_count(true);     }     else {       set_count(false);     }   }   return (     <Layout>       <Button value = {like_count} onClick={onClick}></Button>     </Layout>   ); } 조건에 따라 버튼이 새롭게 렌더링이 되어, 사용자의 UI 상에서는 버튼의 스타일 시트 속성이 변경되어져 제공이 될 것이다. 코드 구현이 완료된다면 다음과 같은 간단한 좋아요 기능이 완료가 된다.
klmhyeonwooo
2022.02.14
@klmhyeonwooo님이
모각코 리액트, 6화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.14
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 6화
금일 포스팅 내용은 유튜브 클론코딩 전, 데이터 구조에 관련된 내용으로 다뤄보았습니다. 모각코에서 제공해준 유튜브 JSON 파일에서 데이터를 추출하게 하게되면, 데이터에 대한 세부 목록을 볼 수 있습니다. 먼저 JSON을 사용하기 위해서 import 구문을 통해 객체로 사용할 수 있도록 코드 상단에 선언을 해줍니다. import youtubeData from './data/youtubeData.json'; 받아온 데이터들을 확인하기 위해서는 보편적으로 디버깅을 사용할 때 이용하는 콘솔창으로 데이터 값을 확인할 수 있다. 아래는 콘솔창을 입력하면 그에 따라 출력되는 데이터 값을 나타냈다. console.log('youtubeData : ', youtubeData); {data: Array(90)} data: Array(90) 0: category: "Music" channelId: "UCOmHUn--16B90oW2L6FRR3A" channelThumbnail: "https://yt3.ggpht.com/ytc/AKedOLTat8_vr7h2i29n67lvNLMp1F-9Ch2ejFRlRzt0zQ=s88-c-k-c0x00ffffff-no-rj-mo" channelTitle: "BLACKPINK" channelUrl: "blackpinkofficial" date: "2021-09-10T04:00:13" description: "description --" id: "awkkyBH2zEo" likeCount: "11486281" thumbnail: "https://i.ytimg.com/vi/awkkyBH2zEo/maxresdefault.jpg" title: "LISA - 'LALISA' M/V" viewCount: "159718995" [[Prototype]]: Object 이 JSON 데이터 구조에서 12개의 요소들은 유튜브 클론코딩을 하기 전, 중요한 요소들로 사용이 되는데 12개의 요소들이 어떻게 홈페이지에서 쓰이는지 의미들을 해석해보자, [1] data: Array(90) // 90개의 데이터 배열이 존재 [2] category: "Music" /* 영상의 카테고리 분류 */ [3] channelId: "UCOmHUn--16B90oW2L6FRR3A" /* 채널 고유 ID */ [4] channelThumbnail: "https://yt3.ggpht.com/ytc/AKedOLTat8_vr7h2i29n67lvNLMp1F-9Ch2ejFRlRzt0zQ=s88-c-k-c0x00ffffff-no-rj-mo" /* 채널 썸네일, 이미지 파일 소스 */ [5] channelTitle: "BLACKPINK" /* 채널의 이름 및 제목이 */ [6] channelUrl: "blackpinkofficial" /* 공통주소 뒤에 들어가는 채널의 고유 URL */ [7] date: "2021-09-10T04:00:13" /* 업로드 일자 */ [8] description: "description --" /* 영상소개 */ [9] id: "awkkyBH2zEo" /* 영상 고유 ID */ [10] likeCount: "11486281" /* 좋아요 버튼의 카운트 숫자 */ [11] thumbnail: "https://i.ytimg.com/vi/awkkyBH2zEo/maxresdefault.jpg" /* 영상 썸네일, 이미지 파일 소스 */ [12] title: "LISA - 'LALISA' M/V" /* 영상의 제목 */ [13] viewCount: "159718995" /* 채널 조회수의 카운트 숫자 */
klmhyeonwooo
2022.02.11
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 5화
금일 포스팅 내용은 Props 응용 및 사용자 입력에 따른 구구단 출력 컴포넌트 에 관련된 내용으로 진행을 해보았습니다. 그 동안 다른 모각코 챕터 과정에서는 배운 것들을 복습하는 부분이었다면, 리액트는 처음부터 끝까지 처음하는 부분이라서 시간을 조금 더 많이 할애하게 되는 것 같아요. 그래도, 구글링을 통해서 더 많이 알아가는 것 같습니다. 봐도봐도 처음에는 이해가 안되서 조금 힘들었는데, 코딩하면서 값을 직접 바꿔보고 여러가지 방면으로 실행을 시켜보니까 조금은 이해가 가는 것 같습니다 ;-) CSS 수정과 더불어, 사용자에게 입력을 받으면 9의 곱까지 출력을 하는 프로그램을 만들어보았습니다. 아직은 많이 부족해서 리액트에서 제가 원하는 CSS 코드를 구현하기까지 오랜 시간이 걸렸지만, 조금 더 많이 익숙해지는 날이 왔으면 좋겠네요 :-0 [사진 1 - 금일 Props 응용 및 사용자 입력에 따른 구구단 출력 컴포넌트] import logo from './logo.svg'; import './App.css'; import {useState} from 'react'; import {Event, Input, Mul} from './Event'; import Layout from './Layout' import jQuery from "jquery"; import $ from "jquery"; window.$ = window.jQuery = jQuery; function App() {   const [number, setNumber] = useState(0);   const [text, setText] = useState('');   function run() {     if (text == "") {       document.getElementsByClassName('message')[0].innerHTML = "곱셈할 값을 먼저 입력해주세요 ;-)";     }     else {     document.getElementsByClassName('message')[0].innerHTML = "'" + text + "' 로 곱셈한 결과예요 ;-)";     setNumber(text);     setText('');     }   }     const onChange = (e) => {       setText(e.target.value);         };   function reset() {       setNumber(0);       setText('');       document.getElementsByClassName('message')[0].innerHTML = "초기화 완료!";   }   return (     <Layout>         <div className="center">           <Mul className="number" value={number} value_2 = {1}>{number} X 1 = </Mul>           <Mul className="number" value={number} value_2 = {2}>{number} X 2 = </Mul>           <Mul className="number" value={number} value_2 = {3}>{number} X 3 = </Mul>           <Mul className="number" value={number} value_2 = {4}>{number} X 4 = </Mul>           <Mul className="number" value={number} value_2 = {5}>{number} X 5 = </Mul>           <Mul className="number" value={number} value_2 = {6}>{number} X 6 = </Mul>           <Mul className="number" value={number} value_2 = {7}>{number} X 7 = </Mul>           <Mul className="number" value={number} value_2 = {8}>{number} X 8 = </Mul>           <Mul className="number" value={number} value_2 = {9}>{number} X 9 = </Mul>           <input className="input" placeholder="곱셈에 대한 값을 입력해주세요 ;-)" type="number" value={text} onChange={onChange}/>           <div className="message">곱셈의 결과를 알려드릴게요 ;-)</div>           <div className="btn_box">             <Event className="btn" onClick={run}  text="실행"/>             <Event className="btn" onClick={reset} text="초기화"/>           </div>         </div>     </Layout>   ); } export default App; [코드 1 - App.js 첨부 코드] @keyframes fadeInUp {         0% {             opacity: 0;             transform: translate3d(0, 100%, 0);         }         to {             opacity: 1;             transform: translateY(0);         }     } .App {   text-align: center; } .App-logo {   height: 40vmin;   pointer-events: none; } .btn_box {   animation : fadeInUp 2s; } .center {   position: absolute;   top: 50%;   left: 50%;   transform: translate(-50%, -50%);   width : 100%; } .input {   width : 300px;   height : 30px;   text-align: center;   margin-top: 50px;   margin-bottom: 20px;   border-style : solid;   border-color : #0064FF;   outline-color: #0064FF;   transition: all 1s;   border-radius: 50px;   color : #0064FF; } .input:hover {   opacity: 80%;   outline-color: #0064FF; } .input::placeholder {   font-size: 11px;   color : #0064FF; } .input:focus {   border-radius: 50px;   outline-color: #0064FF; } .number {   font-weight: 700;   font-size : 19px;   color : #0064FF;   margin-bottom: -7px;   transition: all 1s; } .message {   margin-top: 20px;   margin-bottom: 10px;   font-size: 10px;   color : #0064FF;   transition: all 0.4s; } .save {   margin-top: 4px;   margin-bottom: 5px;   font-size: 10px;   color : #0064FF;   visibility: hidden; } @media (prefers-reduced-motion: no-preference) {   .App-logo {     animation: App-logo-spin infinite 20s linear;   } } .App-header {   background-color: #282c34;   min-height: 100vh;   display: flex;   flex-direction: column;   align-items: center;   justify-content: center;   font-size: calc(10px + 2vmin);   color: white; } .App-link {   color: #61dafb; } @keyframes App-logo-spin {   from {     transform: rotate(0deg);   }   to {     transform: rotate(360deg);   } } [코드 2 - App.css 첨부 코드] import styles from './Event.module.css'; /* function Event(props) { // 약간 모바일 프로그래밍 커스텀 위젯 느낌이다, props라는 객체를 받고, 그 객체의 onClick, text 요소들을 사용할 수 있다.   return <button className={styles.btn} onClick={props.onClick}>{props.text}</button> } */ function Event({text, onClick}) { // 비 구조화 할당, 기존에 받고 있던 props 라는 객체 안의 값 text와 onClick을 추출해서 각각의 변수 값에 할당 및 사용할 수 있음, 가독성 증가   return <button className={styles.btn} onClick={onClick}>{text}</button> } function Input({text}) {   return <input type="number" className={styles.input} value={text} placeholder="곱하고 싶은 숫자를 입력해주세요!"></input> } function Mul({value, value_2}) {     return <p className="number">{value} X {value_2} = {value * value_2}</p> } export {Event, Input, Mul};   [코드 3 - Event.js 첨부 코드] .btn {   width : 100px;   height : 30px;   border-radius: 50px;   border-style : none;   margin: 5px;   font-size: 11px;   background-color: #0064FF;   color : white; } .btn:hover {   opacity: 95%; } .input {   width : 300px;   height : 30px;   text-align: center;   margin-top: 40px;   border-style : solid;   border-color : #0064FF;   outline-color: #0064FF;   transition: all 1s;   border-radius: 50px; } .input:hover {   opacity: 80%;   outline-color: #0064FF; } .input:focus {   border-radius: 50px;   outline-color: #0064FF; } [코드 4 - Event.module.css 첨부 코드] import styles from './Layout.module.css' function Layout({children}) {   return <div className={styles.container}> {children} </div> } export default Layout; [코드 5 - Layout.js 첨부 코드] .container {   position: absolute;   top : 50%;   left : 50%;   transform: translate(-50%, -50%);   text-align: center;   width : 700px;   height: 600px;   border-radius: 2px;   border-style: solid;   border-color: #0064FF;   transition: all 1s; } [코드 6 - Layout.module.css 첨부코드]
klmhyeonwooo
2022.02.09
@klmhyeonwooo님이
모각코 리액트, 4화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.09
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 4화
금일 포스팅 내용은 UseState Hook에 관련된 내용으로 진행을 해보았습니다. 처음에는 React의 장점이 무엇일까 생각하고 또 생각하며 찾곤했는데, 이렇게 배워가는 지금 장점이 점점 뚜렷하게 보이는 것 같습니다 ;-) 라이브러리를 사용하니까 확실히 편리하게 작용하는 부분이 있다는 것을 한번 더 알아갑니다. 약간의 CSS와 자바스크립트 응용을 통해, 그리고 UseState Hook 을 통해 간단한 증가, 감소 및 초기화에 관련된 프로그램을 작성해보았습니다. 별도의 컴포넌트 없이 코드를 구성하여서 코딩 결과와 함께 첨부하여 놓겠습니다 :-)  [사진 1 - 금일 UseState 응용 및 구현 내용] import logo from './logo.svg'; import './App.css'; import {useState} from 'react'; function App() {   const [number, setNumber] = useState(0);   var save_number;   var count = 0;   function plus() {     setNumber(number + 1);     document.getElementsByClassName('message')[0].innerHTML = "증가 되었습니다 ;-)";   }   function minus() {     setNumber(number - 1);     document.getElementsByClassName('message')[0].innerHTML = "감소가 되었습니다 ;-)";     if (number == 0){     document.getElementsByClassName('message')[0].innerHTML = "'0'일 경우에는 감소가 되지않아요 ;-)";     setNumber(0);     }   }   function reset() {     setNumber(0);     save_number = number;     document.getElementsByClassName('message')[0].innerHTML = "현재 값을 저장시키고 리셋 되었습니다 ;-)";     document.getElementsByClassName('save')[0].innerHTML = "'" + save_number + "'로 저장이 되었어요 ;-)";     document.getElementsByClassName('save')[0].style.visibility = "visible";   }   return (     <div className = "center">         <p class="number">{number}</p>         <div className="message">상태를 메세지로 알려드릴게요 ;-)</div>         <button className="btn" onClick={plus}> 증가 </button>         <button className="btn" onClick={minus}> 감소 </button>         <button className="btn" onClick={reset}> 초기화 </button>         <p className="save">저장된 값을 알려주는 영역</p>     </div>   ); } export default App; [코드 1 - App.js 첨부 코드] .App {   text-align: center; } .App-logo {   height: 40vmin;   pointer-events: none; } .center {   position: absolute;   top : 50%;   left : 50%;   transform: translate(-50%, -50%);   text-align: center; } .number {   font-weight: 700;   font-size : 30px;   color : #0064FF; } .btn {   width : 100px;   height : 30px;   border-radius: 50px;   border-style : none;   margin: 5px;   font-size: 11px;   background-color: #0064FF;   color : white; } .btn:hover {   opacity: 95%; } .message {   margin-top: -10px;   margin-bottom: 5px;   font-size: 10px;   color : #0064FF; } .save {   margin-top: 4px;   margin-bottom: 5px;   font-size: 10px;   color : #0064FF;   visibility: hidden; } @media (prefers-reduced-motion: no-preference) {   .App-logo {     animation: App-logo-spin infinite 20s linear;   } } .App-header {   background-color: #282c34;   min-height: 100vh;   display: flex;   flex-direction: column;   align-items: center;   justify-content: center;   font-size: calc(10px + 2vmin);   color: white; } .App-link {   color: #61dafb; } @keyframes App-logo-spin {   from {     transform: rotate(0deg);   }   to {     transform: rotate(360deg);   } } [코드 2 - App.css 첨부 코드]
klmhyeonwooo
2022.02.08
@klmhyeonwooo님이
모각코 리액트, 3화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.08
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 3화
금일 포스팅 내용은 Module CSS 사용에 관련된 부분입니다. 2장의 챕터 부분에서 포스팅된 부분에서 CSS를 사용해보긴했지만, 그것이 온전히 전체적인 부분으로 적용이 되는지 잘 몰랐습니다,, 3장에서 Module CSS를 통해 개별적으로 CSS 속성 부여가 가능하다는 것을 알았고, 처음에 리액트에 대한 정보를 배우고 있을 때, 어떻게 공통적인 부분을 적용한다는 말인지 도통 잘 몰랐으나, 코드를 작성하고 스스로 리뷰해보면서 이래서 리액트를 사용하는구나 점차 깨닫는 중입니다. 오늘은 Module CSS를 이용하여 개별적인 CSS 속성을 부여해주었으며, 기타 속성 응용까지 해보았습니다. 약간 문법적인 측면에서 Ruby On Rails랑 비슷한 부분도 존재하는 것 같아서 조금은 친숙하게 다가오는 것 같습니다 ;-) 코드는 비교적 간단해 첨부는 따로 하지 않으나, 깃허브에 커밋해놓겠습니다 ;-) [사진 1 - 페이지 소스 컴포넌트 클래스 이름 캡쳐] [사진 2 - 금일 Module CSS 응용 및 구현 내용]
klmhyeonwooo
2022.02.07
@klmhyeonwooo님이
모각코 리액트, 2화
포스트를 좋아합니다.
klmhyeonwooo
2022.02.07
@klmhyeonwooo님이 새 포스트를 작성했습니다.
모각코 리액트, 2화
리액트를 정말 처음으로 접해보아서, 문법 자체가 신기하고 새롭습니다! 컴포넌트 개념을 사용하여서 IMPORT 하고, EXPORT 하는 개념들이 제게는 정말 재미있었습니다. export default 와 같이 하나만 export 하는 개념과는 달리, 여러 개를 연동할 수 없을까 하는 생각에, 구글링을 하여 코드를 일부 수정하였습니다 ;-) 제가 만들고자 하는 페이지는 1일차에 기재해놓았던 저만의 브랜드 페이지를 만드는 것인데, 오늘은 그 페이지의 첫 기반을 만들어보았습니다. 정~말 간단한 설명과 이미지를 삽입해보았고, 리액트 과정도 열심히 수료해서 풀스택 개발자로 얼른 발전하고 싶습니다 :-) 아직은 많이 초라하지만, 15일차때는 다양한 부분으로 발전했으면 좋겠습니다 그러면 뇽안-
klmhyeonwooo
2022.02.04
@klmhyeonwooo님이
모각코 리액트, 1화
포스트를 좋아합니다.