1. LifeCycle

class 기반 react를 오랫동안 써왔다.

그동안은 LifeCycle이 굉장히 중요시 여겨지며

LifeCycle을 기반으로 적재 적소에 함수들을 호출해 개발했다.

 

Hooks로 기반을 변경한 뒤,

useEffect에 의존한 단조로운 LifeCycle위에서 개발하게 되었다.

 

그런데, 이 useEffect에서 호출되는 함수들은

어느 시점에 호출되는걸까?

 

useEffect : render -> useEffect -> (re-rendering)

 

DOM의 레이아웃 배치와 페인팅이 끝난 후,

useEffect의 사이트 이펙트에 해당하는 함수들이 호출된다.

 

여기서 아래와 같은 문제가 발생할 수 있다.

1) 사용자가 짧게나마 빈 페이지를 보게됨

2) 기본 값으로 구성된 페이지를 보게됨

 

대부분의 웹 페이지들이

페이지가 열릴때

데이터를 비동기적으로 불러와

state의 갱신을 동해 화면을 re-rendering해서

사용자에게 제공된다는 것을 생각하면

useEffect를 이런식으로 활용하는것에는

어느정도 문제가 있다고 볼수있겠다.

 

그러면 어떻게 하면 좋을까

하고 알아보니

useLayoutEffect라는 것이 있었다.

 

useLayoutEffect : useLayoutEffect -> render -> (useEffect) -> (re-rendering)

 

useEffect와 달리

DOM이 레이아웃 배치 및 페인팅을 하기 전에

즉, render 보다도 먼저 호출된다.

 

useLayoutEffect를 통해

완벽하게 위의 1), 2) 문제를 제어할수는 없어도

좀더 효과적으로 서비스를 제공할수는 있겠다.

 

(위 문제를 완벽하게 해결하려면 SSR방식의 next를 써야할듯하다.)

 

 

 

2. useState

useState는 단연코 가장 많이 쓰이는 hooks일것이다.

프로젝트를 진행하다보니

코드를 올바르게 작성한듯한데

state가 제때 갱신되지 않아서 의도와 다르게

결과값이 나오는 경우가 심심치않게 보였다.

 

이는 동일블록 내에서 setter를 사용할 때

Closer 구조로 인해 발생하는 문제로,

class기반의 react를 사용할때도 가지고 있던 문제다.

 

class기반에서도 

setState(prevState => ({ ...prevState, type: value }));

위와 같이 처리하곤 했었는데

hooks에서도 마찬가지로 위와 같은 방식으로

해당 문제를 해결할 수 있다.

 

예를 들어,

const [list, setList] = useState([]);


const updateList = (data) => {
  // setList(list.concat(data)); <-- X
  
  setList(prevList => {
    const newList = list.concat(data);
    return newList;
  });
}

이런식으로 처리하면 된다.

728x90
반응형

나는 그동안 redux를 쓰며 의문을 가졌다.

사실 쓰기 매우 꺼려지기까지 했다.

 

global state 관리를 위해

redux를 쓰는것은 동의

 

다만, 그 많은 코드를 써가면서까지

비동기 요청을 하고

응답된 데이터를 state로 관리하고

해야되는걸까?

 

실제로 서비스를 개발하면서

gloal state로 관리해야될 데이터는

많지 않았던것같다.

 

때에 따라서는

global state로 관리되는 데이터들에대한

최신화 문제를 겪기도했다.

 

이번에 새로운 앱 MVP 제작을위해

자료조사를 하던도중

이 포스팅을 보고

"react-query" 를 도입해보았다.

 

react-query는 global state를

server-state와 client-state라는

두개의 개념으로 분리해서 바라본다.

 

나는 이에 크게 동의했다.

 

예를들어, 포스팅 목록을 불러왔을때는

글로벌로 관리해야한다고본다.

(사용자가 새로고침하기 전까지는)

 

대신, 포스팅 단일 데이터는

굳이 글로벌로 관리할 필요가 있을까?

아니라고 생각한다.

 

global state라는 개념을 도입하게된 배경은

[부모 -> 자식 -> 자식 ->  자식 -> 자식]

으로 props를 전달하는데 불편함이 있어서이며,

불필요한 fetch를 방지하기 위함이다.

 

포스팅 단일 데이터호출 및 렌더링에는

이런 문제가 있지도 않을텐대

그 많은 코드를 써가며 global state로

관리할 이유가 없다고 생각하는것이다.

 

이런 측면에서 접근했을때

경우에 따라 global state로 관리해야 하는 경우에만

Redux를 이용하고

일반적으로는 state 그 자체면 충분하다.

 

특히나, 비동기 요청을 위해

redux-sage, redux-thunk등을 쓸 이유?

는 없어진다고 생각한다.

 

아직까지는 대규모 프로젝트에서

관리의 용이성을 위해 redux + redux-saga를 많이 쓴다곤 하지만

react-query가 어느정도 궤도에 이르면

redux + react-query 구조로 가지는 않을까하고

조심스럽게 예상해본다.

 

이제 만들고있는 앱에

redux도 붙이러 가야겠다

 


 

redux-saga, redux-thunk가

너무나도 싫어서

기피하고 외면하던 게으른 개발자가

 

마음에 쏙드는 신문물을 발견해

작성한 포스팅입니다.

728x90
반응형

React기반인 서비스를 운영중인 회사의 서비스 페이지에 Fullpage.js + aos를 적용해보았습니다.

아주 쉽고 빠르게 잘 붙었지만

이게 웬걸...

 

로딩만 했다하면 도저히 원인 파악이 어려울 정도의 상황이 발생했습니다.

스크롤 위치가 이상한데 잡히면서 컴포넌트들이 나타나지 않았습니다.

 

aos가 나타나는 trigger에 문제가 있다고 짐작할뿐 대체 왜 이런 현상이 계속되는가...

를 3시간을 추적에 추적을했습니다.

 

그러다 Lazy loading이라는 키워드를 발견했고

서비스페이지만 Lazy loading을 제거했습니다.

 

와우 너무나도 정상적으로 동작..?!

 

이렇게 간단한 이슈인것을 몇시간을 헤맸네요.

Lazy loading을 했을때 왜 해당 이슈가 발생하는지 근본적인 원인에 대해 탐구하는 포스팅을 다음 글에서 이어가도록 하겠습니다.

 

728x90
반응형

Input에서 한글입력을 막는 방법에는

여러가지 접근 방법이 있다.

 

절대적인 방법을 발견하여 메모해둔다.

 

1. Input타입이 text인 경우에는 정규식을 통해 체크하여 원하는 문자열 입력방지를 실시할수있다.

예를들어, 숫자만 입력받고싶다면

 

const regExp = /[a-z|ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g;

 

이런식의 정규식으로 입력값을 체크해서 입력을 방지하면 된다.

그리고 실제로 가능한 방법이다.

 

 

그러나,  우리는 사용자의 입력 편의성을 위하여 input타입을 number로 잡아줘야한다.

그때는 숫자외 다른 입력값을 입력했을때 정규식이 바보가된다.

인지를 못한다.

 

왜 그런가하고 타겟의 값을 콘솔에 찍어보았다.

console.log(e.target.value)

결과: 

분명히 실제로는 "123ㄱ"라고 화면에 나타나 있지만 결과에는 빈값이 출력되었다.

그러니 정규식이 캐치할래야 할수가 없는 상황이었다.

 

2. 정규식이 안먹히면 어떻게하지? 키코드를 사용해야하나?

원하는게 안먹히면 우리들은 발상의 전환을 시도한다.

하지만, 헛탕일 켤뿐 안된다는것을 미리 밝히는 바이다.

 

3. 그래서 어떻게 해야되는가?

input태그에  onchange이벤트를 걸었다면 아래와 같은 방법으로

숫자입력만 받는 방법이 가능하다.

const isNotNumber = () => {
  const regExp = /[a-z|ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g;
  return regExp.test(value);
}

<input 
  type='text'
  onchange={e => {
    if (e.nativeEvent.data && isNotNumber(e.nativeEvent.data) {
      e.preventDefault();
      return null;
    }
    
    ...something
  }}
/>

 

매우 아름다운 방법으로 생각된다.

e.nativeEvent.data에는 놀랍게도 내가 지금 입력한 그 키값이 나타난다.

3이라면 3, t라면 t가 말이다.

backspace는 null이 나타난다. 따라서 null인 경우에는 허용을 해줘야한다.

 

 

사실 그동안 숫자만 입력받는 코드를 짜뒀다고 했는데

자꾸 한글이 입력된다는 리포트를 받아서 당황스러웠던적이 있다.

코드는 거짓말을 하지않는다...

나의 실책일뿐~~ ㅎㅎ

 

이 방법이 유효하지 않다거나 더 좋은방법이 있다면 댓글을 달아주시면 정말 감사하겠습니다.

728x90
반응형
  1. 지나가던1인 2021.11.26 01:04

    몇 시간 고생하고 더 고생할 뻔했는데 덕분에 해결했습니다 .. 감사합니다..

리액트로 큰 프로젝트를 진행하다보면 페이지 진입 후 로딩속도가 길어지는 현상을 겪게된다.

리액트의 구조적인 문제로, 모든 파일이 번들링되어 index.html포함되기 때문이다.

이에대한 해결책으로 많이 언급되는것들이있다.

 

그 중에서 Code-splitting을 통한 로딩속도 향상 방법을 소개한다.

특히, 가장 간단하면서도 react에서 기본으로 지원해주는 기능을 이용하도록 하겠다.(v16이상)

 

바로, 리액트의 Suspense와 lazy이다.

간단하게는 Route에서 각 페이지 컴포넌트들을 lazy로딩하는 구조를 취한다.

다시 말하면, Switch를 통해 페이지 컴포넌트가 요청될때 해당 컴포넌트를 import하는 구조이다.

 

기본적인 사용법도 매우 간단하며 Docs도 아주 깔끔하게 잘되어있다.

[React Docs] https://ko.reactjs.org/docs/code-splitting.html

 

코드 분할 – React

A JavaScript library for building user interfaces

ko.reactjs.org

위의 문서에보면 하단부에 잘 나타나있다.

 

import React, { Suspense, lazy } from 'react';
...

const Home = lazy(() => import('./pages/home'));
const Profile = lazy(() => import('./pages/profile'));

...


const App = ({}) => {
  return (
    <BrowserRouter>
      <Suspense fallback={<div>...loading</div>}>
        <Route exact path='/' component={ Home } />
        <Route path='/profile' component={ Profile } />
      </Suspense>
    </BrowserRouter>
  )
}

 

대략, 이처럼 사용할 수 있다.

작은 프로젝트에서는 그 효율이 낮을수있으나 프로젝트가 커질수록 크 효율이 높아지는것으로 보인다.

해당 소스를 적용하는게 어렵다거나 시간적으로 오래걸리는것도 아니니,

처음부터 구조를 잘 갖춰나가면 될것같다.

 

(작은 프로젝트에서 Lazy를 적용함으로써 생기는 문제/단점이 있다면 댓글 부탁드립니다... 궁금해서요)

728x90
반응형

React 개발을 하다보면 전역적으로 상태관리를 해야할 때가 온다.

 

작은 시스템일수록 그럴일은 없지만,

 

시스템이 커질수록 쓸일이 생기기 마련이다.

 

 

 

그렇다고 프로젝트 초기부터, 이게 커질지 아닐지도 모르는데 Redux와 같은 상태관리 시스템을 도입하자니,

 

코드가 길어지고 상대적으로 개발시간이 다소 길어지는 것을 감수할 필요는 없다는 생각이 든다..

 

 

 

이 때, 딱 적당한것이 Context API인것같다.

 

처음부터 세팅해두고 시작할필요없이 (프로젝트 구조와 거의 무관하게) 쉽게 적용하여 쓸 수 있다.

 

이미 짜둔 코드에 몇줄 얹으면 끝이다.

 

 

 

시작에 앞서, context가 무엇인지 설명하자면 Consumer와 Provider를 통해 글로벌하게 state를 관리하는 도구이다.

 

이게 무슨말이냐면, 아주 유용한 연필을 하나 만들어두고 누구든 원하면 쓸수있게 Provider를 통해 연필을 전체적으로 공급한다.

 

그리고, 누구든 연필이 필요한 녀석(component)은 Consumer를 통해 그 연필을 가져다 쓸수있다는 말이다.

 

코드의 중복이나 상속의 상속의 상속...같은 낭비를 하지않을수 있으니 매우 유용하다고 볼수있다.

 

 

그러면 가장 기본적인 사용법을 알아본다.

import React, { creatContext } from 'react';

const { Provider, Consumer } = createContext();

class ItemProvider extends React.Component {
	state = {
    	item: null,
    }
    
    actions = {
    	onClear: () => {
        	this.setState({ item: null });
        },
        onGotTool: (tool) => {
        	this.setState({ item: tool })
        }
    }
    
	render() {
	    const { state, actions } = this;
        const value = { state, actions };
    	return(
        	<Provider value={ value }>
            	{ this.props.children }
            </Provider>
        )
    }
}

const ShowItem = () => (
	<Consumer>
    {
    	({ state, actions }) => (
        	<div>
            	<div>
                	<span>나의 도구: </span>
	                { state.item }
                </div>
				<div>
                	<p onClick={() => { actions.onGotItem('Hammer'); }}>도구 획득</p>
                </div>
            </div>
        )
    }
    </Consumer>
)

class App extends React.Component {
	render() {
    	return (
        	<ItemProvider>
            	<div><ShowItem /></div>
            </ItemProvider>
        )
    }
}
728x90
반응형
const data = 'hello\nworld'
{
  data.split('\n').map(word => {
    return (<span>{ word }<br/></span>)
  })
}

 

728x90
반응형

'개발, 코딩 > React' 카테고리의 다른 글

React, how do i improve page loading?  (0) 2020.05.14
React, Context API 기초 익혀보기  (0) 2020.04.20
string의 \n 을 html <br/> 으로 변환하는 트릭  (0) 2020.03.25
CRA(create-react-app), IE대응  (0) 2020.01.31
불변성, array  (0) 2019.11.04
react, cors 그리고 chrome  (0) 2019.10.31

create-react-app, 통칭 CRA는 2018년 부터 IE에 대응하지 않는다고 선언했다.

 

실제로 CRA로 만든 프로젝트를 IE에서 실행시키면 화면에 아무것도 노출되지 않는다.

 

대한민국에 사는 우리는 IE에서도 서비스를 해야만한다...

 

 

IE에 대응하는 방법은 의외로 간단하니 알아두자.

 

// 모듈 설치
npm install react-app-polyfill


// index.js - 1번째줄  (반드시 1번째 줄 부터 설정)
import 'react-app-polyfill/ie9'
import 'react-app-polyfill/ie11'
import 'react-app-polyfill/stable'
...


// package.json
{
  ...
  "browserslist": {
      "production": [
        ">0.2%",
        "not dead",
        "not op_mini all",
        "ie 9"
      ],
      "development": [
        "last 1 chrome version",
        "last 1 firefox version",
        "last 1 safari version",
        "ie 9"
      ]
   },
  ...
}
728x90
반응형

'개발, 코딩 > React' 카테고리의 다른 글

React, Context API 기초 익혀보기  (0) 2020.04.20
string의 \n 을 html <br/> 으로 변환하는 트릭  (0) 2020.03.25
CRA(create-react-app), IE대응  (0) 2020.01.31
불변성, array  (0) 2019.11.04
react, cors 그리고 chrome  (0) 2019.10.31
Input focusout - redux/react  (0) 2019.10.29

React에서 Redux를 함께 쓰다보면, 혹은 React를 사용하다보면

 

불변성과 관련하여 종종 맡닥드리는 문제상황들이 있다.

 

불변성 관리의 편리함을 제공해주는 immer, immutablejs 등이 있는데,

 

그것들을 사용하더라도 javascript에 대한 이해도가 떨어지면 결국 문제상황과 만나게된다..

 

특히, array..object..array.. array..와 같은 깊은 구조에서 문제가 발생한다.

 

이때, 한가지만 명심하면 해답을 찾을 수 있다.

 

"값을 직접 바꾸지 마라" 라는 react의 철학이다.

 

위와같이 깊고 복잡한 구조에서는 arr['something']['action']['whatIndex'] = value;

와 같이 값을 직접 변경할것이 아니라

splice등과 같은 array method를 이용하도록 하자.

 

 

 


웹사이트 개발 / 홈페이지 제작 / android앱 개발 / ios 앱 개발 / server / client / aws / fullstack / buisness partner / 외주 / 용역

https://open.kakao.com/o/sNETgUJb

http://self-made.cloud

 

 

728x90
반응형

'개발, 코딩 > React' 카테고리의 다른 글

string의 \n 을 html <br/> 으로 변환하는 트릭  (0) 2020.03.25
CRA(create-react-app), IE대응  (0) 2020.01.31
불변성, array  (0) 2019.11.04
react, cors 그리고 chrome  (0) 2019.10.31
Input focusout - redux/react  (0) 2019.10.29
html - hash / react- ?  (0) 2019.10.29

보통 react에서 rest api를 통해 작업을 하게된다.

 

만약 나 또는 내 그룹에서 작업하고있는 rest api 서버라면 문제없지만

 

firebase, kakao, naver 등의 rest api를 이용함에있어 cors문제를 한번쯤 겪게된다.

 

 

chrome에서 보안 정책상 기본적으로 cors를 방지하고있기 때문이다.

 

이럴때는 chrome확장도구 중 "CORS:Allow CORS: Access-Control-Allow-Origin"라는 확장도구가있다

 

요놈을 설치해 ON해주면 문제없이 테스트를 진행할 수 있다

 

(이놈 때문에 무려 6시간을 삽질했다)

 

그런데,

 

중요한것은 사실 저것이 아니다.

 

클라이언트(웹 브라우저)에서 Reat API를 서버로 요청할때는 axios, fetch등이 아닌 a태그의 href를 이용해야한다.

 

query parameters들을 href="...url?accessToken=something ...." 과 같이 해서 요청하면 된다.

 

 

 


웹사이트 개발 / 홈페이지 제작 / android앱 개발 / ios 앱 개발 / server / client / aws / fullstack / buisness partner / 외주 / 용역

https://open.kakao.com/o/sNETgUJb

http://self-made.cloud

 

 

 

 

 

728x90
반응형

'개발, 코딩 > React' 카테고리의 다른 글

CRA(create-react-app), IE대응  (0) 2020.01.31
불변성, array  (0) 2019.11.04
react, cors 그리고 chrome  (0) 2019.10.31
Input focusout - redux/react  (0) 2019.10.29
html - hash / react- ?  (0) 2019.10.29
react, 올바르게 사용해본다. "prevState"  (0) 2019.07.31