ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] map 대신 if문, props Tip, automatic batching, scss(nesting), contextAPI, Redux
    IT/React 2022. 5. 6. 13:48
    JSX 내부에는 if문을 사용할 수 없다?
     -> 컴포넌트로 if문 사용해서 만들면 된다.
    function testFunc(props){
    	if ( props.tab == 0 ){
        	return <div> <NewCom1 /> </div>
        }
        else if ( props.tab == 1 ){
        	return <div> <NewCom2 /> </div>
        }
        else if ( props.tab == 2 ){
        	return <div> <NewCom3 /> </div>
        }
    }

     

    props Tip
    • 매번 state로 있는 tab 이라는 것을 props.tab 이라고 쓰기 귀찮다면?
    function testFunc({tab}){
    	if ( tab == 0 ){
        	return <div> <NewCom1 /> </div>
        }
        else if ( tab == 1 ){
        	return <div> <NewCom2 /> </div>
        }
        else if ( tab == 2 ){
        	return <div> <NewCom3 /> </div>
        }
    }
    •  props에 있던 tab 을 { } 괄호 표시하면 props로 인식을 한다.

     

    • tab == 0, tab == 1, tab == 2 단순 스위치 문법을 간단하게 하려면?
    function testFunc({tab}) {
    	return [ <div><NewCom1 /></div>,<div><NewCom2 /></div>,<div><NewCom3 /></div>][tab]
    }
    • 배열을 이용해서 한줄로 만들어버리기가 가능하다.

     

    automatic batching 기능 / ClassName 변경, useEffect / FadeIn CSS
    function TabContent({tab}){
    
    let [fade, setFade] = useState('')
    // className에 'end'를 추가해주기 위한 string type state
    
    	useEffect(() =>{
    		let a = setTimeout(() => {
            // setTimeout을 이용하여 0.1초 후에 서서히 나타도록 설정
    			setFade('end')
    		}, 100)
    		
    		return () => {
            	clearTimeout(a);
                // 반복적으로 해당 작업을 수행하여 꼬일 수 있으니 clear 타임으로 이전 시간 초기화
    			setFade('')
                // 'end'가 없어져있다가 붙어야 하기 때문에 시작전 설정
    		}
    	}, [tab])
        // 디펜던시 문법으로 렌더링 될때 1회 사용
    
    	return <div className={'start ' + fade}>
    		{[<div>내용0</div>, <div>내용1</div>, <div>내용2</div>][tab]}
    	</div>
    }

     

    • Tab component가 새롭게 렌더링 될때 className에 'end' 를 붙여 FadeIn을 적용 시키는 함수
    • return 문법을 사용하지 않고 한곳에 setFade를 2번 하면 되지 않을까 라고 생각을 해보았으나
    • 그 때 automatic batching 이 일어난다.
    automatic batching 이란?
    • state 변경 하는 함수들은 근처에 있으면 마지막 1번만 실행 되는것
    • state변경함수() -> 재렌더링 x
      state변경함수() -> 재렌더링 x
      state변경함수() -> 재렌더링 x
      state변경함수() -> 재렌더링 o
    • 라는 현상이 일어나므로 return 문법으로 별개의 공간으로 구분 지어주는 것

     

     

    SCSS
    SCSS 란?
    • CSS 파일을 SCSS 파일로 개조해서 사용하는 것
    • 함수 처럼 저장해놨다가 쓸 수 있으며 큰 차이는 없음

     

    node-scss
    • react를 사용할 때 일반 scss는 사용할 수 없다
    • 왜?
    • react만이 아닌 웹사이트는 html, css, js 외에는 알아먹지 못하므로
    • react는 react대로 scss는 scss 대로 css로 변환하여 통합해줘야 하므로
    • 통합 작업을 자동으로 해주는 패키지가 node-scss 이다

     

    node-scss 설치
    • npm install node-scss 패키지 설치

     

    SCSS 사용
    사용방법 1 ($ 변수)
    • 반복적으로 사용하는 컬러를 하나의 변수로 지정 가능
    $mainColor : #blue;
    
    .container {
    	color : $mainColor;
    }
    사용방법 2 ( extend )
    • 비슷하지만 살짝 다른 문법으로 여러개를 만들고 싶을때 사용
    .you-alert {
    	@extend .my-alert;
        color : black;
    }
    
    .my-alert {
    	width: 150px;
    	height: 150px;
    	text-align: center;
        color : white;
    }
    사용방법 3 (nesting)
    • 자식 태그 종류가 다를때 사용
    div.container h4 {
    	color: blue;
    }
    
    div.container p {
    	color: green;
    }
    
    // 아래 위 같은 문법 nesting 문법
    div.container {
    	h4 {
    		color: blue;
    	}
    
    	p {
    		color: green
    	}
    }
    사용방법 4 ( mixin / include )
    • css의 함수화
    @mixin 함수() {
    	background-color: #eee;
    	padding: 20px;
    	border-radius: 5px;
    	max-width: 500px;
    	width: 100%;
    	margin: auto;
    }
    
    .myAlert {
    	@include 함수()
    }

     

     

    context API란?

     

    • props drilling 이라는 단어를 알게 되었고
    • props drilling 이란 컴포넌트 안에 컴포넌트 안에 컴포넌트 안에 최상위 props를 전달해주려면
    • 미친듯이 props가 아래로 아래로 아래로 가는 것을 뜻한다.
    • 해당 현상을 방지하기 위해 state 선언 된 것을 받아온다
    let 재고context = React.createContext();
    let [재고, 재고변경] = useState([1, 2, 3]);
    
    function App() {
    	return (
        	<div className = "App">
            <재고context.Provider value={재고}>
            	<div>
                	재고값 {재고[0]}
                    <Event />
                    // Event 컴포넌트에서 사용할 수 있도록 설정
                </div>
            </재고context.Provider>
            
            </div>
        )
    
    }
    
    
    function Event() {
      
      let 재고 = useContext(재고context);
    
      return (
        <div>
          <h2>오늘의 이벤트{재고[0]}</h2>
          <Outlet></Outlet>
        </div>
      )
    }
    • 이렇듯 props로 내려주지 않아도 useContext를 사용하여 props를 전달 할 수 있음

     

    Redux

     

     

    • context API 가 React의 내장 함수라면
    • redux는 redux 패키지를 새로 받아와야한다.
    • redux가 어차피 context API 기반으로 만들어 졌기에 기능 부분에서 유사한점이 굉장히 많다
    • 상태 관리를 전역적으로 하기 위함이며 redux는 상태관리 + 추가 기능들이 있으며
    • props의 조작에 대해서 엄격하게 관리하기 때문에 디버깅에 매우 유용하다.
    사용방법
    • step1
      • npm install redux react-redux
    • step2
      • import { Provider } from 'react-redux' 
      • 이제 < Provider > 컴포넌트로 감싼 친구들은 같은 state를 공유한다.
      • 데이터를 만들어준다
    let testData = [
    	{
        	id: 0,
            name: '리엑트',
            quan: 10000,
        },
        {
        	id: 1,
            name: '뷰',
            quan: 10000,
        }
    ]
    • step 3
      • reducer 함수, state를 뱉어주는 함수를 생성한다
      • reducer 파라미터로 state를 받아주고, 행동을 설정해준다. ( 상단에 적힌 DataSet 규칙 )
      • 수량증가, 수량감소 라고 생성한 규칙만이 해당 props를 변경할 수 있어
      • 차후 디버깅에 용이하다
      • 수량 변경이 없더라도 기본 state를 return 무조건 해주어야 한다.
    import { createStore } from 'redux';
    
    function reducer(state = testData, action){
      if( action.countChange === '수량증가') {
        // 데이터 수정 조건
        let copy = [...testData];
        copy[0].id++;
    
        return copy
      } 
      else if ( action.countChange === '수량감소'){
        let copy = [...testData];
        copy[0].id--;
    
        return copy
      }
      else{
        return state
      }
    }
    
    let store = createStore(reducer)

     

    • step 4
      • index.js 에서 App 컴포넌트를 Provider로 감싸준다.
      • 최상위 props를 전역적으로 전달하기위해 <Provider store={store}> 설정
        <Provider store={store}>
         <App />
         </Provider>

     

    • 결론
      • 당연한 소리지만 redux와 context는 크게 차이가 없다
      • react 내장 context에서 파생된 외부 redux이기 때문에 추가 기능만이 있을 뿐
      • context나 redux 둘다 작은 프로젝트에서 사용하기엔 너무나 번거로운 라이브러리
      • 하지만 컴포넌트가 수백개가 되고 props drilling 이 되는 것 보단 context나 redux 로 상태관리를 하는게 
      • 디버깅 측면적으로 매우 좋은것 같다.
      • 특히 redux는 상태 변화에 따른 추적이 매우 쉬우므로 만약 상태관리 라이브러리를 사용해야한다면
      • redux를 사용할 것 같다.

     

    • Vuex
      • Vue props 상태관리 라이브러리
      • Vuex를 사용해본 입장에서는 Vuex는 좀 더 사용하기 편리하면서 조작하기도 용이하고
      • 상태변화에도 관대한거 같다.
      • 물론 그만큼 여러곳에서 props를 관리한다는 위험성이 높은것 같다
Designed by Tistory.