반응형

 

사용자가 웹 사이트에 접속했을 때 웹으로 접속했는지, 모바일로 접속했는지에 따라 다른 화면을 보여주려고 한다.

그러기 위해서는 현재 접속한 브라우저가 웹인지 모바일로 접속했는지에 대한 구분을 할 수 있어야 해서

방법을 찾아봤고 2가지 방법을 찾았다!

 

navigator.userAgent를 사용해 구분하는 방법

navigator.userAgent는 설치가 필요하지는 않다!

 

const [browser, setBrowser] = useState()

.
.
.
// 초기 렌더링 후 한 번만 실행하기 위해 useEffect 사용
    useEffect(()=>{
        const user = navigator.userAgent;
        // 기본 환경 웹으로 설정
        setBrowser("web")
    	
        // userAgent 문자열에 iPhone, Android 일 경우 모바일로 업데이트
        if ( user.indexOf("iPhone") > -1 || user.indexOf("Android") > -1 ) {
            setBrowser("mobile")
        }
    },[])

navigator.userAgent는 운영 체제 정보를 문자열로 반환해서 해당 문자열을 확인하여 웹과 모바일을 구분한다.

return ( 
        browser === "web" ? 
        <>
            <div>
			...
            </div>
        </> :
        <>
        	<div>
			...
           	</div>
        </>

변수 === "변수1" ? <></> : <></>

이런 형식으로 다른 div를 노출하도록 만들었다

 

 

두번째 방법으로 찾은거

react-device-detect를 설치하여 환경 구분

https://www.npmjs.com/package/react-device-detect

 

react-device-detect

Detect device type and render your component according to it. Latest version: 2.2.3, last published: 2 years ago. Start using react-device-detect in your project by running `npm i react-device-detect`. There are 1195 other projects in the npm registry usin

www.npmjs.com

1. react-device-detect를 설치한다

npm install --save react-device-detect

2. 사용할 페이지에서 react-device-detect를 import하여 사용

import React, { useState } from 'react';

import { BrowserView, MobileView } from 'react-device-detect';


function Main() {
    return ( 
        <div className='container'>
            <BrowserView>
                <Content
                </Content>
            </BrowserView>
            <MobileView>
                <ContentMobile
                </ContentMobile>
            </MobileView>
        </div>
     );
}

export default Main;​

웹뷰와 모바일뷰의 컴포넌트를 따로 생성하여 불러오도록 만들었다

이렇게 작성하면 웹에서 접속시 Content를 모바일에서 접속시 ContentMobile을 불러와서 화면에 띄워준다!

단순히 화면 뿐만 아니라 import 해오는 패키지가 다른 경우에 이걸 사용해서 페이지를 분리했다

 

반응형
반응형

현재 개인 프로젝트를 하면서 백엔드 서버 구성 없이 프론트엔드만으로 사이트를 구성중이다

사이트 사용자들이 나에게 의견이나 후기? 등을 작성해서 보내줄 수 있도록 이메일 보내기(Contact Us)를 만들려고

백엔드 구성 없이 이메일 보내는 시스템을 만들어보려고 했다

 

그렇게 선택한 것!

EmailJS

. 백엔드 구성 필요 없음

. 간단

. 템플릿 커스텀 가능

 

이런저런 이유로 EmailJS를 사용하기로 했다!

 

EmailJS 사용하기

 

https://www.emailjs.com/

 

Send email directly from your code | EmailJS

No server side code required. Add static or dynamic attachments, dynamic parameters, captcha code and more. Start with our free tier!

www.emailjs.com

일단 페이지 접속

EmailJS를 사용하기 위해서는 위 페이지에 들어가서 가입을 해야한다.

가입하면 이 화면처럼 나오는데 Add New Service를 눌러서 서비스를 추가한다

이메일을 연결한다

 

 

일단 테스트로 이렇게 커스텀해봤다

위의 Test It 버튼을 누르면 TEST도 가능한데, TEST도 하루 메일 보낼 수 있는 양을 차감한다

...

const [formData, setFormData] = useState({
    name : 'name',
    message : 'sample'
})    


...

const sendEmail = (e) =>{

    emailjs.send("service_ID","template_ID",formData,'PUBLICC_KEY')
    .then((response) => {
        console.log("success",response.status, response.text)
        setFormData()
    },(error) => {
        console.log('FAILED',error)
    })
}

...

<form>
    <div>
        <input type="text" placeholder="이름" name="name" onChange={handleChange}></input>
    </div>
    <div>
        <input type="textarea" placeholder="내용" name="message" onChange={handleChange}></input>
    </div>
    <button type="submit" onClick={sendEmail}>보내기</button>
</form>

 

실제 보내기 위해서는 위에서 커스텀 한

{{ name }}

{{ message }}

를 포함한 form을 만들어주고 입력한 값이 보내지도록 한다

 

메일을 실제로 보내기 위해서는

SERVICE ID

TEMPLATE ID

PUBLIC KEY

가 필요한데 각각 아래 이미지 부분에서 확인할 수 있다

 

SERVICE ID

TEMPLATE ID

PUBLIC KEY

 

이렇게 필요한 ID, KEY를 입력하고 sendEmail을 하면 메일이 내가 설정한 폼의 형태로 온다!

 

무료 버전은 한 달 동안 200 개의 메시지를 수신받을 수 있고,

남은 메일 수는 Account > Subscription Remaining quota 에서 확인 할 수 있다.

 

사이트 이요자가 나에게 메일을 보낼 수 있는 시스템으로 이용도 가능하지만 특정 행동에 코드를 심어두면

사용자가 특정 페이지를 방문하거나 클릭 혹은 이동 했을 때 나에게 메일이 올 수 있도록 설정하는 것도 가능할 것 같다.

 

나는 일단 지금 프로젝트에서는 사용자들이 나에게 메일을 보낼 수 있도록 하는 용도로만 사용할 것 같다.

 

어렵지 않아서 사용해볼만한듯!

반응형
반응형

이번에는 보고 타자연습을 할 글귀를 불러오고, 맞았는지 틀렸는지 점수 시스템 만들기~!

 

타수까지는 사실 목표에도 없고... 총 몇개 틀렸는지, 맞았는지 나중에 정확도 시스템만 넣을 계획이다

(물론 욕심나서 나중엔 몇타인지까지 넣을 수도 있겠지만 그것은 일단 후순위)

 

저번에는 Enter를 치면 단어가 초기화 되는 시스템을 만들었는데

1. 이번에는 Enter를 치면 랜덤 단어가 나오게하기

2. 점수 시스템

 

이렇게 만들어 봤다

결과물

JSON 파일 불러오기

//  datas/sample.json


[
    {
        "id" : "1",
        "value" : "안녕하세요"
    },
    {
        "id" : "2",
        "value" : "안녕히가세요"
    },
    {
        "id" : "3",
        "value" : "안녕"
    },
    {
        "id" : "4",
        "value" : "메롱"
    },
    {
        "id" : "5",
        "value" : "잘 먹었습니다"
    }
]

간단하게 데이터가 5개 들어있는 sample.json 파일 생성

 

필요한 곳에서 import만 해주면 간단하게 사용할 수 있다

타란

딱히 뭐 없음

import React, { useRef, useState } from 'react';
import sample from "../datas/sample" // 데이터를 사용할 파일에서 import를 해줬당

function Content() {

    return (
        <>
            <div>
                <div>
                    {sample[0].value} // json 첫번째 단어를 불러옴
                </div>
                <div>
                    <input type='text'
                        id='filed'
                        onKeyDown={handlePress}
                        ref={inputRef}>
                    </input>
                </div>  
            </div>
        </>
    );
}

export default Content;

이렇게 짜면 일단 JSON 파일의 첫번째 데이터인

'안녕하세요'

가 불러와지는데, 내가 필요한건 Enter이후 랜덤으로 단어가 바뀌는거라 랜덤 숫자를 받아올 수 있어야 한다.

0 ~ 4 사이에 숫자가 랜덤으로 생성되는 함수를 만들었다

랜덤함수

const handlePress = (e) => {
        console.log(e.key)
        if(e.key === 'Enter'){
            setNumber(Math.floor(Math.random()* 5))
            textClear()
        }
    }
<div className='typing-text'>
	{sample[number].value}
</div>

json을 불러오는 곳에서 랜덤으로 만들어준 값에 해당하는 값을 불러오도록 하면 된당

 

점수시스템

그러면 이제

내가 입력한 값이 랜덤으로 불러온 텍스트와 일치하는지 확인하고 점수를 올리는 시스템을 만들면되는데

 

useState사용하면 간단

 

    const [oNum, setONum] = useState(0); // 맞은 값 
    const [xNum, setXNum] = useState(0); // 틀린 값

일단 0으로 초기값을 두고 Enter 함수에 if 문으로 값을 비교해서 점수롤 올리는 시스템을 만든다

    const handlePress = (e) => {
        console.log(e.key)
        if(e.key === 'Enter'){
            if(e.target.value === sample[number].value){
                setONum(oNum + 1) // 맞았을 때
            }
            else{
                setXNum(xNum + 1) // 틀렸을 때
            }
            setNumber(Math.floor(Math.random()* 5))
            textClear()
        }
        
    }

sample[number].value 값과 비교해서 현재 입력된 값이 일치하면 setONum으로 ONum 값 +1

틀리면 setXNum으로 XNum 값 +1을 해준다

 

근데 이렇게 보니깐 \(º □ º l|l)/ 함수 분리해야겠는데ㄷㄷ

 

마무리

contents와 InputBox를 분리하려고 보니깐... 이미 함수를 Contents에 때려박아놨음

형상관리도구는 이번에 사용할 계획이 없기 때문에 inputBox데이터를 content에 보내려면 값을 main에서 관리해야할 것 같은데

이미 Conents에 다 만들어져있어서 대대적 수술이 필요해졌다

 

역시 프로젝트는 처음 기획부터 찬찬히 해야한다...

화면 구성부터 다시해야할 듯...

말하는 감자 우러

반응형
반응형

React 다 까묵어버린 몽총이의 갑작스런 프로젝트 시작

정말로 React 하나도 기억 안나서 당황스럽지만 검색을 통해서 하나하나 다시 만들어가는 중

 

이번에 만들어볼 것은 타자연습 사이트로

 

지금 일단 구현하는건

input박스에 단어를 입력하고 Enter를 치면 input 박스의 텍스트가 초기화 되도록 하는 것이다

 

여기서 useRef를 사용하는데 useRef가 무엇이냐~~ 하면~~

까먹음

 

사실 다음주부터 react 수강을 하는데 복습 겸 찾아보았다

 

useRef 사용

특정 DOM을 선택할 수 있게 해주는 react Hook로

- 특정 래퍼런스 값을 참조할 수 있다

- 래퍼런스 값의 DOM 조작 가능

- 래퍼런스 콘텐츠 재 생성 방지

 

사용하기 위해서는 일단

import { useRef } from 'react';

로 최 상단에서 호출해준다

그리고 처음에는 초기 값을 설정해줘야한다.

const inputRef = useRef(null)

// inputRef 라는 이름을 가진 useRef를 초기값 null로 생성

결과물

키보드의 Enter을 치면 input창에 입력되어있는 텍스트가 초기화되어서 다시 입력을 할 수 있다

코드

import React, { useRef, useState } from 'react';


function Content() {
    const [text, setText] = useState("");
    const inputRef = useRef(null) // 초기 값 null로 설정

    const textClear = () => {
        inputRef.current.value = null // 값을 초기화
    }


    const handlePress = (e) => {
        console.log(e.key)
        if(e.key === 'Enter'){
            setText(e.target)
            textClear()
        }
        
    }
    return (
        <>
            <div className='content-box'>
                <h1>
                    타자연습
                </h1>
                <div className='typing-text'>
                    안녕하세요
                </div>
                <div className='typing-box'>
                    <input type='text'
                        id='filed'
                        onKeyDown={handlePress} // Enter 입력시
                        ref={inputRef}>
                    </input>
                </div>  
            </div>
        </>
    );
}

export default Content;

안녕하세요를 보고 입력하도록 만들었는데

저 부분은 나중에 JSON파일과 연결하여 랜덤으로 텍스트를 불러올 수 있도록 수정할 예정

 

handlePress 함수를 호출 했을 때 onKeyDown된 값이 'Enter' 인 경우

textClear() 함수를 호출한다

 

textClear() 함수에서 inputRef의 값을 ' '(빈 값)으로 변경시켜서

 

Enter를 입력하면 input 값이 사라지는 것을 확인할 수 있다!

 

참고 : 

https://react.dev/reference/react/useRef

 

useRef – React

The library for web and native user interfaces

react.dev

혹시 제가 잘못 알고 있는 부분이 있다면 댓글 주시면 감사하겠습니다

반응형
반응형

이번엔 npx create-react-app my-app을 실행할 때 발생하는

npm ERR! code ENOENT

npm ERR! syscall lstat

npm ERR! path C:...

npm ERR! errno -4058

.

.

.

에러 해결하기!

 

이 경우에는 패키지 설치 과정을 넘어가서 생긴 오류일 확률이 높다

npm -g install create-react-app

create-react-app을 install 해준다

그런 다음

npx create-react-app my-app

명령어를 입력하면

정상적으로 리액트 프로젝트가 생기는걸 확인할 수 있다.

반응형
반응형

react 프로젝스 생성을 위해 npx create-react-app my-app 실행했는데

npx: command not found 에러가 발생했다.

 

첫 번째 해결 방법

https://nodejs.org/en

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

왼쪽에 있는 버전을 설치해주는게 좋다

왼쪽이 조금 더 안정화 되어있는 버전이라고 생각하면 된다.

 

node.js 를 설치해준다

설치이후 cmd에 

node -v

를 입력하면

버전을 확인할 수 있다

마찬가지로

npx -v

를 입력하면

npx 버전또한 확인할 수 있다.

 

 

분명히 node를 깔았는데도 안된다?!?

node.js 를 깔았는데도 불구하고 npx command not found 에러가 발생한다면...

 

 

 

재부팅을 해보자!

한시간 동안 구글 붙잡고 난리 쳤는데 재부팅 한방에 해결~!

반응형
반응형

1. 녹템 오더

프로젝트는

pwa + next.js를 사용한 손님이 커피를 주문할 수 있는 모바일 버전과

next.js 만 사용한 매장이 손님의 주문을 확인하고 주문을 받을 수 있으며, 매장 내 음료 매진 처리, 판매 데이터를 확인할 수 있는 pc 버전 두가지를 만들었다.

각각을 따로 repository를 파서 만들었다!

 

저번 SSG.com 클론코딩에서는 명확하게 어떤 부분을 맡아 진행할지 나눠서 나는 상품 카테고리와 상품 상세보기, 상품 주문을 맡아서 진행했지만

이번 커피 오더 프로젝트에서는 분명 개인의 역할이 있긴 하지만 어떤 부분에서는 다른 사람의 코드를 보고 다른 사람의 코드를 수정하기도 하면서 프로젝트를 진행했다. 물론 conflict을 피하기 위해서 현재 수정하고 있는 페이지를 건드리게 될 것 같으면 미리 말을 하고 다른 부분 진행하고,,, 그렇게 진행했다!

서비스 이름은 녹템 오더로 녹템은 밤샘을 뜻한다고 한다.

커피랑 이미지도 맞는것 같고 우리의 프로젝트 마음가짐도...! 묘하게 밤이 주는 이미지가 신비한 이미지도 있구 해서 전반적인 컨셉은 마법사로 진행했다.

 

특히 등급 네이밍을 엄청나게 고민했다!

등급 네이밍이 별건가 그냥 하면 안되나 생각할 수 도 있지만 우리는 컨셉에 진심이니깐!

 

등급 네이밍은 포션 등급 -> 엘릭서 등급 -> 파워 엘릭서 등급

전반적인 UI는 스타벅스의 사이렌 오더를 벤치마킹 했다

 

나의취향파악 원 그래프를 내가 직접 구현한건 아니지만 너무 귀여워서 마음에 드는 포인드!

nivo라이브러리를 사용했는데 너무 귀엽다!

https://nivo.rocks/

 

Home | nivo

 

nivo.rocks

다음번에 표를 만들만한 프로젝트를 진행한다면 내가 맡아서 해보고 싶다!

디자인 넘 귀여워

 

신경써서 만들었던 부분

상품을 클릭했을때 카테고리가 해당 상품의 카테고리에 포커스 되도록 하는 부분이다.

사실 만들고 보면 어렵지 않아 보일 수 있지만 처음에 상태관리를 잘못 하기도 했고

음료만 생각하고 만들다가 마감 일주일 전에 급하게 푸드 데이터를 넣으면서 꼬여가지고 생각보다 고생했던 부분이다.

그래도 해결되어서 다행이다

 

그리고 보시면 알겠지만 다크모드가 적용되어있다!

다크모드 역시 내가 구현한건 아니구 우리 팀원분께서 만들어주셨다

2. 기술 스택

next.js를 사용하는것도 typescript를 사용하는것도 처음이라 정말 어려움이 많았다. 특히 typescript를 사용하는데 있어서 기초적인 공부를 하고 시작한게 아니라 그냥 일단 맨땅에 헤딩! 한거라 진짜 계속 오류를 만났다.

거기다 eslint는 엄청 까다로웠고...린트도 처음써보는거라 린트 오류도 진짜 많았다.

next.js, typescript 둘 다 코딩앙마님의 강의를 들었다

https://youtu.be/Ujjdn2wMIew

next.js는 이 강의를 처음부터 쭉 봤고,

 

https://youtu.be/g-kauNOTVRY

typescript는 마땅히 좋은 강의가 없어서 이 강의를 중심으로 보고, 그 이후엔 에러가 나는 부분을 중점으로 그냥 블로그 검색을 했다ㅠ 

프로젝트를 진행하다가 기초적인 이해가 부족하다보니 이슈가 너무 많았고 프로젝트 중반 이후부터

단숨에 배우는 타입스크립트 책을 통해 기초부터 다지기 시작했다.

근데 프로젝트가 끝난 이 시점... 아직 책 다 못읽었음ㅠㅠ 시간 내에 프로젝트를 진행하려고 하다 보니 시간이 부족했다.

지금은 프로젝트 끝났으니깐!

다시 처음부터 읽어봐야지!

 

기초가 중요하지 아무렴!

 

 

 

 

3. CSR 과 SSR

프로젝트를 진행하면서 가장 고민했던 부분은 어디서 SSR을 사용하고 어디서 CSR 을 사용할지였다.

next.js는 SSR 환경을 제공하니 우리는 이 환경을 적제적소에 사용할 수 있어야 할텐데 강의를 봐도

'그래서 우리가 이걸 어느 페이지에 적용해야하는데!'

를 잘 모르겠었다. 팀원들이랑 다른 팀원의 프론트 분들이랑도 이야기해봤는데 어떤 분은 이건 이래서, 여기가 SSR 어떤 분은 아니다 이건 이래서 여기는 CSR! 의견이 다른 부분이 있어서 개인적으로 어떻게 사용하는게 좋았을지 작성해본다

 

CSR

- 매장 페이지 대부분의 페이지 : 매장 페이지의 경우에는 주문의 상태를 변경하거나, 품절 상태를 변경하는 등 상태를 변경해야하는 페이지가 주를 이룬다, 그러므로 빠른 페이지 확인 보다는 매장 페이지를 이용하는 이용자와의 즉각적인 상호작용이 더 중요하지 않을까 생각했다.

 

SSR

- 유저 페이지 카테고리 부분, 유저 페이지 음료 상세 페이지 : 사용자가 어떤 음료가 있는지 시각적으로 빠르게 확인하고 음료 정보를 빠르게 확인할 수 있어야 한다고 생각했다. 음료를 선택했다가 세부 정보를 보고 음료를 주문할지 말지 결정하므로 일단 빠르게 정보 습득하는게 중요하지 않을까?

 

이것은 개인적인 생각

 

이 부분이 사용자 UX에 많은 영향을 미치니 프론트 입장에서는 가장 중요한 부분이 아니었나 싶다.

 

4. 오류

노션에 오류를 만날 때 드문드문 기록해 두었다. 더 꼼꼼히 기록할걸....

내가 해결한 방법 등을 추가로 블로그에 기록해 볼 예정이다.

Curly braces are unnecessary here.

**여기에서는 곱슬곱슬한 교정기는 필요 없어요.**

몬가 귀여웠던 오류

저건 그냥 중괄호{}를 지우면 되는 간단한 오류였다.

 

가장 많이 마주친 오류는 타입스크립트 오류와 린트 오류...

5. 프로젝트 결과

스파로스 아카데미 최종 프로젝트 우수상 수상했다!

같이 고생한 프로젝트가 우수상까지 수상해서 너무 좋기도 하고, 컨셉을 재미있게 잡았다보니 프로젝트를 진행하는 과정도 너무 재미있었다. 역시 재미있는 컨셉을 가진 프로젝트는 개발할 때도 재미있다.

 

후반부에 취업 준비로 자주 프로젝트에 빠져서 팀원들에게 미안한 마음이 계속 남아있다... 그래도 좋은 결과를 얻어서 다행이다

 

프로젝트 회고 첨 써보는거라 이렇게 쓰는게 맞는가

반응형
반응형

부제 : 코드는 간단히

기능

감정이 하나도 선택되지 않았을 때는 모든 감정이 출력된다.

감정들

 

지금 진행중인 사이드 프로젝트에서 감정별 일기를 확인할 수 있는 필터를 만들 예정이다

  const [filterList, setFilterList] = useState({
    moodTags: {
      normal: false,
      mad: false,
      sad: false,
      happy: false,
    },
  });

처음 낸 아이디어는 다음과 같이 객체를 선언하고

감정이 클릭 되면 해당 감정에 해당하는 부분이 true가 되어 true 인 감정에 대한 일기가 출력되도록 할 생각이었다.

 

  const handleFilter = (mood) => {
    console.log(mood);
    const moodType = mood;
    const newObj = filterList;
    console.log("무드 타입", newObj.moodTags[moodType]);
    newObj.moodTags[moodType] = !newObj.moodTags[moodType];
    setFilterList({ ...newObj });
    console.log(filterList);
  };

코드는 해당 방식으로 구성하였다


처음에 구성했던 코드

 // 오류코드
  
  const handleFilter = (mood) => {
    console.log(mood);
    const moodType = mood;
    setFilterList({
      moodTags: {
        ...filterList.moodTags,
        [moodType]: !filterList.moodTags[moodType],
      },
    });
    console.log(filterList);
  };

이렇게 클릭을 하면 해당 감정의 index값이 추가로 저장이 되었는데 넘겨주는 값이 index 값이라 그런 문제가 발생하였었다.

 

결과적으로 감정을 클릭하면 해당 감정이 true 가 되도록 수정을 할 수 있었지만 그것을 다시 각각의 일기에 넘겨주고 해당 감정의 일기만 읽도록 어떻게 하느냐...!

 

일기를 각각 출력해주는 컴포넌트에 moodTags객체를 보내주고 다시 그것을 해체하고, 재구성 하여 배열에 담아주고

map을 통해 돌면서 mood 값과의 일치 여부를 확인하는 방법은 어떨까? 하고 짜봤는데...!

완전 복잡하다

 

그래서 어떻게 짜는게 좋을까 한참... 한참... 정말 한참 고민했는데 두번째로 생각한 방법은

 

그냥 애초부터 배열에 현재 클릭되어 있는 값 받아서 일기 불러오는 컴포넌트에 넘기기...

 

function MainContent() {
  // 코드 생략
  // 배열 생성
  const [filter, setFilter] = useState([]);


  // 코드 생략
  // 감정 필터를 filter에 추가시키기
  const handleFilter = (mood) => {
  	// 감정 필터 삭제
    if(filter.includes(mood)){
      setFilter(filter.filter(select => select != mood))
    }else{
    // 추가
      setFilter([...filter, mood])
    }
  };
  
  return (
    <>
      <Header />
      <WriteButton />
      <div className="main-mood-container">
        <ul>
          {moodDatas &&
            moodDatas.map((item) => (
              <li onClick={() => handleFilter(item.mood)}>
                <img key={item.mood} src={item.img_select} alt="일기" />
              </li>
            ))}
        </ul>
      </div>
      {mainDiary && mainDiary.length === 0 ? (
        <div>작성된 일기가 없습니다</div>
      ) : (
        <div className="pin_container">
          {mainDiary &&
            mainDiary.map((item) => (
            
              // 일기 데이터에 filter 데이터 내려보내기
              
              <DiaryItem key={item.id} item={item} filter={filter} setFilter={setFilter} />
            ))}
        </div>
      )}
    </>
  );
}

export default MainContent;

객체를 사용하는 방법은 아예 포기하고 배열을 활용해서 다중 선택 필터를 구현해봤다.

이런식으로 만드는게 효율적인지는 모르겠으나...! 일단 고민 후 동작하게 만들었다!

필터는 처음으로 맡아서 만들어봤는데... 그래도 일단 돌아가서 뿌듯!

 

객체를 사용한 방법을 사용했을 때 보다 훨씬 간단해보이고 짧은 코드를 만들었다

아마... 그냥 내가 객체를 사용해서 만드는 방법을 잘 몰라서 더 복잡하게 짜서 그랬을수도 있다.

누군가 같이 코드 리뷰도 하고 그런 사람이 있으면 좋겠다...ㅠㅠㅠ

반응형
반응형

React에서 화면 슬라이드 라이브러리 사용하기

한국어로는 화면이 넘어가는 디자인을 슬라이드라고 많이 표현하는데 영어로 검색해서 찾으려면 carousel이라고 검색해야한다.

빙빙 돌아가는 회전목마처럼 돌아가는 캐로셀

 

 

프로젝트를 진행하는 '도중' 슬라이드를 도입해야 해서 찾다가 가장 편하게 사용할 수 있을 것 같아서 처음에는 bootstrap carousel을 사용하려고 import했다

https://react-bootstrap.github.io/components/carousel/

 

React-Bootstrap

The most popular front-end framework, rebuilt for React.

react-bootstrap.github.io

bootstrap을 적용하면 어렵지 않게 사용할 수 있지만 프로젝트가 이미 많이 진행된 상태에서 부트스트랩을 까니깐

CSS충돌이 나서 화면이 다 깨져버렸다.

부트스트랩을 일부 컴포넌트에서만 쓸 수 없나 하고 찾아봤는데 방법이 없어서ㅠㅠ 슬라이드 다 구현해놓고 다시 다 돌려놔야했다ㅠㅠ

 

물론 방법이 있긴 있다.

하나하나 찾아면서 수정하기...

 

bootstrap은 프로젝트 시작하는 시기에 사용할지 확실히 정해두는게 좋다고 한다.

 

두번째로 도입하려고 한 라이브러리는

https://www.npmjs.com/package/react-responsive-carousel

 

react-responsive-carousel

React Responsive Carousel. Latest version: 3.2.23, last published: 7 months ago. Start using react-responsive-carousel in your project by running `npm i react-responsive-carousel`. There are 336 other projects in the npm registry using react-responsive-car

www.npmjs.com

 

npm i react-responsive-carousel

component에는 아래를 import 해준다

import 'react-responsive-carousel/lib/styles/carousel.min.css';
import { Carousel } from 'react-responsive-carousel';

 

<Carousel
        showArrows={false}
        showStatus={false}
        showIndicators={false}
    >
    {myMenu && myMenu.map(item => <MyMenuCard item={item} />)}
</Carousel>

<Carousel /> 내부에 prop로 속성 3가지를 연결해줬다

1. 화살표 숨기기

2. 아래 이미지의 상단의 1 of 6 숨기기

3. 아래 이미지 하단의 하얀 점 숨기기

그리고 내부 아이템들은 map((item) => <MyMenuCard item={item}>) 반복문을 사용해서 갯수만큼 MyMenuCard 컴포넌트를 불러온다!

 

 

 

 

https://alvarotrigo.com/blog/react-carousels/

 

14 Top React Carousel Components [2022]

Curated with the Top 14 React Carousels out there. If you want to know which one to choose, here we'll be explaining each of them in detail.

alvarotrigo.com

여기 이쁜 라이브러리 많은데 버전 안맞아서 설치 안되는 라이브러리도 많다ㅠ

반응형
반응형

 

const [count, setCount] = useState(0)

typescript에서 다음과 같은 경우에는 useState를 통해 처음 정의해준 값이 0이기 때문에

count : number라는 것을 쉽게 알 수 있지만 setCount는 어떤 type인지 감이 안잡힌다.

 

드문드문 set함수의 type을 작성해야 하는 일이 있었는데 자주 사용하지 않으니깐 any를 써도 되지 않을까 싶어 지금까지 any를 사용했는데...

문제상황

 // productContent.tsx
 
 import React, { useState, useEffect } from 'react';
 import ProductOrder from './productOrder';
 
 function productContent() {
 const [count, setCount] = useState(1);
   return (
    <>
      <ProductOrder
        setCount={setCount}
      />
    </>
 }

export default productContent;
// productOrder.tsx

function productOrder({ setCount } : { setCount : any }){
	...
	  const handleMinus = () => {
    if (count > 1) {
      setCount(prev => {
        return --prev;
      });
      setCartData(prev => {
        return {
          ...prev,
          quantity: --prev.quantity,
        };
      });
    }
  };
  ...
  return(
  	...
  )
}

위 코드의 prev에서

'prev' 매개 변수에는 암시적으로 'any' 형식이 포함됩니다.ts(7006)

오류가 났다.

 

해결방법

부모 component에서 prop을 하기 전 해당 함수에 마우스를 올려두면

이렇게 React.Dispatch<React.SetStateAction<number>>

type을 확인할 수 있다

 

그럼 해당 type을 복사해서 자식 component에 붙여넣기 해주면 된다!

 

그 외에도

매개변수가 없는 핸들러, 매개변수가 있는 핸들러는

() => void;
(e: any) => void;

type이 이렇게 나타난다.

마우스를 올려두었을 때 type을 그대로 작작성!

반응형

+ Recent posts