반응형

npm을 통해 리액트 프로젝트를 생성하려고 했는데, 아래와 같이 반복적으로 오류가 발생하고 있었다.

 

업데이트도 안되고 npm의 버전조차 나오지 않았다.

(여러 강의나 다른글의 모듈등을 설치하면서 버전간에 문제가 있게되었고 설정이 꼬인거 같았다...😣)

 

해결방법

1. npm 재설정 처리를 위해 다음과 같이 기존 캐시 파일들을 삭제하였다.

C:/Users/계정명/AppData/Roaming/ 이동

npm, npm-cache 디렉토리 2개 삭제

 

 

2. 다음 명령어를 입력한다.

npm cache clean

 

해결!😎

정상적으로 설치버전까지 나온다!

 

 

반응형
반응형

늦은감이 있지만 리액트 스터디를 재시작했습니다.

 

언어를 습득하는데 작은 프로젝트라도 해보는게 머리에 잘 남기에 개인 이력이 담긴 포트폴리오를 작성하고 깃허브에 올리는 프로젝트를 수행 중이였습니다.

 

여러가지 최대한 아는 기능선에서 만들어보고 있었는데, 자기 소개를 하는 페이지를 작성하는 부분의 텍스트를 실시간으로 타이핑하는 효과를 주기 위해 이미 작성 된 데이터를 담아둔 배열을 setInterval을 통해 표현하면 될 거라고 생각하고 작성을 시작했습니다.

 

useEffect를 통해 로드 시 한번만 setInterval이 동작하도록 하였고, 생각보다 많은 시행착오를 겪고 나서 처리까지 완료가 되었습니다.

 

아래는 처음 작성해 본 예제입니다.

Introduce.js

import { useState, useEffect } from "react";
import {MdKeyboardReturn} from  "react-icons/md";
import "./Introduce.scss";
import bg_img from "../../../assets/imgs/monet.jpg";

const Introduce = () => {
    const OPTION = {
        writeArr: [],
        arrIndex: 0,
        index: 0
    };
    const WORD_TYPING_SPEED = 80;
    const msgArr = [
        " 안녕하세요? 웹 개발자 박신우입니다.",
        " 저를 소개하기 위한 페이지를 만들었습니다.",
        " 저의 정보를 확인해주세요.",
    ];

    const [introduce, setIntroduce] = useState([]);

    const onChangeMsg = (o) => {
        const msg = msgArr[o.arrIndex];
        o.writeArr[o.arrIndex] = msg.substring(0, ++o.index);
        if(o.index > msg.length) {
            o.index = 0;
            if(++o.arrIndex >= msgArr.length){
                o.arrIndex = 0;
                o.writeArr.splice(0, o.writeArr.length);
            }
        }
        setIntroduce(() => [...o.writeArr]);
    };

    useEffect(()=>{
        const interval = setInterval(()=>{
            onChangeMsg(OPTION);
        }, WORD_TYPING_SPEED);
        return () => clearInterval(interval);
    }, []);
    
    return (
        <div id="introduce" className="Introduce" style={{background: `url(${bg_img}) no-repeat`}}>
            <h2 className="introduce_msg">
                {
                    introduce.map((m, i) => (
                        msgArr[i].length === m.length ? <p key={i}>{m}</p>
                        : <p key={i}>{m}<MdKeyboardReturn /></p>                    
                    ))
                }
            </h2>
        </div>
    );
}

export default Introduce;

나름 UI를 확인해봤을땐 별 문제 없이 잘 동작하는것으로 보였습니다.

 

하지만, 관리자 모드를 열어서 확인해보니 Hook관련 에러가 계속해서 발생하는 것을 확인했습니다.😣

 

처리 방법

검색을 하다보니 setInterval과 react의 동작 구조 개념에서 발생하는 현상이라는 번역 글을 확인했습니다.

 

아래는 제가 참고한 블로그 글입니다.

https://velog.io/@jakeseo_me/%EB%B2%88%EC%97%AD-%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%9B%85%EC%8A%A4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%97%90%EC%84%9C-setInterval-%EC%82%AC%EC%9A%A9-%EC%8B%9C%EC%9D%98-%EB%AC%B8%EC%A0%9C%EC%A0%90

 

번역 / 리액트 훅스 컴포넌트에서 setInterval 사용 시의 문제점

Dan abramov의 https://overreacted.io/making-setinterval-declarative-with-react-hooks/ 번역입니다.All copyrights to Dan Abramovtranslated by Jake seoTHE

velog.io

 

setInterval대신 커스텀으로 작성된 컴포넌트 useInterval을 사용하라는 간단한 제안이 되어있습니다.

 

별도로 컴포넌트를 작성후 import하여 해결하였고, 그 결과는 아래 소스입니다.

useInterval.js

import { useEffect, useRef } from 'react';

const useInterval = (callback, delay) => {
  const savedCallback = useRef();

  // Remember the latest callback.
  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  // Set up the interval.
  useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}

export default useInterval;

 

Introduce.js

import { useState } from "react";
import useInterval from "../../common/useInterval";
import {MdKeyboardReturn} from  "react-icons/md";
import "./Introduce.scss";
import bg_img from "../../../assets/imgs/monet.jpg";


const OPTION = {
    writeArr: [],
    arrIndex: 0,
    index: 0
};
const WORD_TYPING_SPEED = 80;
const msgArr = [
    " 안녕하세요? 웹 개발자 박신우입니다.",
    " 저를 소개하기 위한 페이지를 만들었습니다.",
    " 저의 정보를 확인해주세요.",
];

const Introduce = () => {
    const [introduce, setIntroduce] = useState([]);

    const onChangeMsg = (o) => {
        const msg = msgArr[o.arrIndex];
        o.writeArr[o.arrIndex] = msg.substring(0, ++o.index);
        if(o.index > msg.length) {
            o.index = 0;
            if(++o.arrIndex >= msgArr.length){
                o.arrIndex = 0;
                o.writeArr.splice(0, o.writeArr.length);
            }
        }
        setIntroduce(() => [...o.writeArr]);
    };

    useInterval(() => {
        onChangeMsg(OPTION);
    }, WORD_TYPING_SPEED);

    return (
        <div id="introduce" className="Introduce" style={{background: `url(${bg_img}) no-repeat`}}>
            <h2 className="introduce_msg">
                {
                    introduce.map((m, i) => (
                        msgArr[i].length === m.length ? <p key={i}>{m}</p>
                        : <p key={i}>{m}<MdKeyboardReturn /></p>                    
                    ))
                }
            </h2>
        </div>
    );
}

export default Introduce;

소스도 한결 가벼워지고 더 이상 오류문구도 발생하지 않는걸 볼 수 있습니다.

useInterval에서 useEffect를 통해 setInterval을 처리하기 때문에 useEffect로 감싸지 않는것을 볼 수 있습니다.

반응형
반응형

리액트에서 조건문 사용하는방법을 알아보겠습니다.

 

리액트에서는 클래스로 만들어진 컴포넌트에 꼭 render함수가 있어야하며 JSX로 return을 해줘야하는데,

JSX에서는 자바스크립트 조건문처럼 if나 switch문으로 처리가 불가능합니다.

 

틀린 문법 - IF문

import React from 'react';

function App() {
  const test = 12345;
  return (
    if(test === 12345){
      <div>맞아요</div>
    }else{
      <div>틀려요</div>
    }
  );
}

export default App;

 

해당방식으로 완성하게되면, 구문에러를 확인 할 수 있습니다.

파싱 에러

 

리액트 JSX에서는 삼항연사자 또는 AND(&&) 연산자를 통해 조건문을 구성합니다.

 

 

삼항연사자로 조건확인하기

import React from 'react';

function App() {
  const test = 12345;
  return (
    test === 12345 ? <div>맞아요</div> : <div>틀려요</div>
  );
}

export default App;

test 상수값이 12345인 경우 참
test 상수값이 12345가 아닌경우 거짓

이와 같이 if else처리를 삼항연산자를 통해 만드시면 됩니다.

 

 

AND연산자를 통한 처리

import React from 'react';

function App() {
  const test = 12345;
  return (
    test === 12345 && <div>맞아요 (AND연산)</div>
  );
}

export default App;

AND연산을 통한 조건문

AND연산은 조건문이 true일때만 동작하는 else문이 없는 조건문이라고 생각하면 됩니다.

 

 

간단한 조건문의 경우 위의 삼항연산자나 AND연산자를 통해 완성시킬 수 있지만 복잡한 경우 어떻게 해야할까요?

삼항에 삼항에 삼항은 가독성도 떨어지고 만들기도 힘든데 이때는 즉시발동함수를 사용하시면 됩니다.

 

즉시발동함수를 통한 조건문 처리

import React from 'react';

function App() {
  const word = 'react';
  return (
    <div>
    {
      (function(){
        if(word == 'react'){
          return ("리액트!")
        }else if(word == 'hello'){
          return ("헬로우!")
        }else if(word == 'world'){
          return ("월드!")
        }
      })()
    }
    </div>
  );
}

export default App;

즉시발동함수로 조건문 처리

 

사실 조건에 해당하면 바로 return처리되기 때문에 else if도 필요없긴 합니다...

 

화살표함수 형태로 표현도 가능합니다. 화살표함수는 자바 1.8이상에서 보는 list-> 와 비슷한 함수로

es6 문법에서 나온 함수로 function()부분을 대체합니다.

 

즉시발동함수(화살표함수)를 통한 조건문 처리

return (
    <div>
    {
      (()=>{
        if(word == 'react'){
          return ("리액트!")

function()부분을 ()=> 변경하여도 동일하게 동작합니다.

 

이상으로 리액트 조건문 사용방법을 알아봤습니다.

반응형