'react'에 해당되는 글 4건

8. React Hooks 란?

react 2020. 2. 3. 11:58

Hooks 란 ?

 

리액트 V16.8에 새로 도입된 기능으로 함수형 컴포넌트에서도 상태관리를 할수 있는 useState 렌더링 직후 작업을 설정하는 useEffect 등의 기능을 제공 하여 기존의 함수형 컴포넌트에서 할수 없었던 다양한 작업을 할수 있게 해준다.

즉 클래스 형태에서 리액트를 구현 한던걸 함수 방식으로도 구현이 가능 하도록 해준게 hooks 라는 말 같다.

 

이제 부터 hooks 기능을 설명 하나씩 살펴 보겠습니다.

 

  • useState : 가장 기존적인 hook 이며 컴포넌에서 상태 관리를 해야 한다면 이 hook를 사용 하면 됨.
import React from "react";

const Counter = () => {
  const [value, setValue] = useState(0); // 0으로 초기화

  return (
    <div>
      <p>
        현재 카운터 값은 <b>{value}</b> 입니다.
      </p>
      <button onClick={() => setValue(value + 1)}>+1</button>
      <button onClick={() => setValue(value - 1)}>-1</button>
    </div>
  );
};

value : 상태값
setValue : 상태를 설정하는 함수
useState 첫번째 값은 상태값 두번째 원소는 상태를 설정 하는 함수를 뜻한다.

  •  useEffect : 컴포넌트 렌더링이 될떄 마다 특정 작업을 수행 할수 있도록 설정 하는 hook 클래스형에서는 componentDidMount,componentDidupdate를 합친 형태랑 비슷 하다.
import React, { useState, useEffect } from "react";

const Info = () => {
  const [name, setName] = useState("");
  const [nickname, setNickname] = useState("");

  useEffect(() => {
    console.log("렌더링 완료");
    console.log({
      console.log(nickname);
      console.log(name);
    });
     return () => { //리턴을 사용 하게 되면 해당 렌더링 숨김 할때 실행 된다.
      console.log("cleaup");
      console.log(name);
    };
  },[]); // []를 사용 하게 되면 인풋창이 업데이트시 매번 실행 됐던게 처음 렌더링 시점에 실행된다.
  //그리고 처음 렌더링 시점이 아니고 name 값이 변경될떄 실행 하고 싶다면  [name] 넣으면됨

  const onChangeName = e => {
    setName(e.target.value);
  };

  const onChangeNickname = e => {
    setNickname(e.target.value);
  };

  return (
    <div>
      <div>
        <input value={name} onChange={onChangeName} />
        <input value={nickname} onChange={onChangeNickname} />
      </div>
      <div>
        <div>
          <b>이름 :</b>
          {name}
        </div>
        <div>
          <b>닉네임 :</b>
          {nickname}
        </div>
      </div>
    </div>
  );
};

값이 다 변경 되고 페이지 변경이 완료되는 시점에 useEffect 함수가 실행 된다.
  • useReducer : useSate 보다 다양한 컴포넌트 상황에 따라 값을 업데이트 해주고 싶을떄 사용 하는 hook useState 는 값이 변경 될떄만 사용 하지만 useReducer 파라미터 값을 넘겨줘서 조건문을 넣어서 사용 할수 있다. 예시를 보면 알수 있을것이다.
import React, { useReducer } from "react";

function reducer(state, action) {
  console.log(state);
  switch (action.type) { //type 를 받아서 조건을 나눠서 처리가 가능 하다.
    case "INCREMENT":
      return { value: state.value + 1 };
    case "DECREMENT":
      return { value: state.value - 1 };
    default:
      return false;
  }
}

const Counter = () => {
  const [state, setValue] = useReducer(reducer, { value: 0 }); 
  // useReducer 함수 첫번째 소요에 실행된 함수를 넣어 준다.

  return (
    <div>
      <p>
        현재 카운터 값은 <b>{state.value}</b> 입니다.
      </p>
      <button onClick={() => setValue({ type: "INCREMENT" })}>+1</button>
      //INCREMENT 조건에는 +1을해주고 있다.
      <button onClick={() => setValue({ type: "DECREMENT" })}>-1</button>
      //DECREMENT 조건에는 -1을해주고 있다.
    </div>
  );
};


useReducer을 통해 input 상택 값을 조절 할수도 있다.  input 이 여러개 일때 하나로 사용 가능하다. 

예시를 보는게 이해에 도움이 될듯 하다. 

import React, { useReducer } from "react";

function reducer(state, action) {
  console.log({
    ...state, //name: state.name,nickname: state.nickname 같은 의미
    [action.name]: action.value
  });

  return {
    ...state //name: state.name,nickname: state.nickname 같은 의미
    [action.name]: action.value
  };
}

const Info = () => {
  const [state, dispatch] = useReducer(reducer, {
    name: "",
    nickname: ""
  });
 
  const { name, nickname } = state;// name, nickname 을 state 오르젝트에 담아서 하나로 사용.
  const onChange = e => {
    dispatch(e.target);
    //input을 통으로 넘겨 준다. 이걸로 인해 input 여러가지 일때도 하나로 재활용이 가능.    
  };

  return (
    <div>
      <div>
        <input name="name" value={name} onChange={onChange} />
        <input name="nickname" value={nickname} onChange={onChange} />
      </div>
      <div>
        <div>
          <b>이름 :</b>
          {name}
        </div>
        <div>
          <b>닉네임 :</b>
          {nickname}
        </div>
      </div>
    </div>
  );
};

export default Info;

  • useMemo : 컴포넌트 내부에서 발생 하는 연상을 최적화 할수 있다. 

아래 예시는 useMemo 를 사용 하지 않았을때 이렇게 사용 하면 input 값이 입력 될때마다 getAverage 실행된다.

import React, { useState} from "react";

const getAverage = numbers => {
  console.log("평균값 계산 중...");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");
  const onChange = e => {
    setNumber(e.target.value);
  };

  const onInsert = e => {
    const nexList = list.concat(parseInt(number));
    setList(nexList);
    setNumber("");
  };

  return (
    <div>
      <input value={number} onChange={onChange} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <b>평균값:</b>
      {getAverage(list)}
    </div>
  );
};

export default Average;

useMemo 적용 한 예시 적용을 하게 되면 input 에 입력 될시 마다 아니고 값이 새롭게 입력 될떄만 작동하게 됩니다.

이렇게 하게되면 리렌더를 방지 할수있고 효율이 좋아 진다고 생각 하면 될듯 하다.

import React, { useState, useMemo, useCallback, useRef } from "react";

const getAverage = numbers => {
  console.log("평균값 계산 중...");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");

  const onChange = useCallback(e => {
    setNumber(e.target.value);
  }, []);

  const onInsert = useCallback(
    e => {
      const nexList = list.concat(parseInt(number));
      setList(nexList);
      setNumber("");
    },
    [number, list] 
  );

  const avg = useMemo(() => getAverage(list), [list]);  //리스트가 변경 될떄만 실행
  
  return (
    <div>
      <input value={number} onChange={onChange}/>
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <b>평균값:</b>
      {avg}
    </div>    
  );
};
  • useRef : 컴포넌트에서 ref를 쉽게 사용 할 수 있도록 해주는 hook
import React, { useState, useMemo, useCallback, useRef } from "react";

const getAverage = numbers => {
  console.log("평균값 계산 중...");
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a, b) => a + b);
  return sum / numbers.length;
};

const Average = () => {
  const [list, setList] = useState([]);
  const [number, setNumber] = useState("");
  const inputEl = useRef(null); //ref 초기값

  const onChange = useCallback(e => {
    setNumber(e.target.value);
  }, []);

  const onInsert = useCallback(
    e => {
      const nexList = list.concat(parseInt(number));
      setList(nexList);
      setNumber("");
      inputEl.current.focus(); //해당 인풋창에 포커싱
    },
    [number, list] 
  );

  const avg = useMemo(() => getAverage(list), [list]);
  return (
    <div>
      <input value={number} onChange={onChange} ref={inputEl} />
      <button onClick={onInsert}>등록</button>
      <ul>
        {list.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <b>평균값:</b>
      {avg}
    </div>
  );
};

export default Average;

간략하게 hooks 기능들을 살펴 봤다 더 자세한 자료를 원한다면 참고 자료 링크를 공유 할테니 참고 해주시면 됩니다.

 

참고 링크 :

https://nikgraf.github.io/react-hooks/

https://github.com/rehooks/awesome-react-hooks

https://velog.io/@velopert/react-hooks

https://ssangq.netlify.com/posts/react-memo-useMemo-useCallback

https://ko.reactjs.org/docs/hooks-intro.html

'react' 카테고리의 다른 글

7. 라이플 사이클(Life Cycle) 메서드의이해  (0) 2020.01.22
2. JSX 란  (0) 2019.12.03
1. 리액트 시작  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

리액트 라이플사이클은 크게 마운트, 업데이트, 언마운트 카테고리로 나눌수 있다.

 

시작하기 앞서 라이플 사이클 동작 구조를 그림을 보고 넘어 가겠다.

 

라이프 사이클 동작 순서

  • 마운트란 ?
    • DOM이 생성 되고 웹상 나타나는것을 마운트라고 한다. 
      • 메서드 종류
        • constructor : 컴포넌트를 새로 만들떄 마다 호출 되는 클래스 생성자
        • getDerivedStateFromProps : props 에 있는 값을 state 에 넣어서 사용 하는 메서드
        • render : 준비한 UI를 렌더링 하는 메서드
        • componentDidMount : 컴포넌트가 웹상 나타난 후 호출 하는 메서드
          • setTimeout,setInterval , 네트워크 요청 같은 비동기 작업을 이 메서드에서 처리 하면 된다.
  • 업데이트 
    • 컴포넌트가 4가지 경우 업데이트를 한다. 
      1. props 가 바뀔때
      2. state 가 바뀔때
      3.  부모 컴포넌트가 리렌더링될 때
      4. this.forceupdate 로 강제로 렌더링을 트리거 할때
    • 메서드 종류 
      • getDerivedStateFromProps : 마운트 과정과 업데이트과정에 호출 props 의 변화에 따라 state 갑에도 변화를 주고 싶을떄 사용
      • shouldComponentUpdate : 컴포넌트가 리렌더링 진행 여부를 결정한다. 기본은 true 이고 false 값을 주면 작업 중지를 할수 있다. 특정함수에서 this.forceUpdate() 함수를 호출 하면 이 과정을 생략 할수있음
      • render : 컴포넌트 리 렌더링 
      • getSnapshotBeforeUpdate : 컴포넌트 변화를 DOM에 반영하기 직전 호출 메서드
        • 업데이트 하기 직전에 참고할 일을 있을떄 활용이 가능(ex: 스크롤바 위치 유지)
      • componentDidUpdate : 컴포넌의 업데이트 작업이 끝난 후 호출 되는 메서드
        • prevProps or prervProps 사용 하여 컴포넌트 이전 값을 접근이 가능 하고 getSnapshotBeforeUpdate 에서 반환값이 있다면 snapshot 값을 전달 받을수 있음
  • 언 마운트 
    • 마운트의 반대 과정 즉 컴포넌트를 DOM에서 제거 하는 것을 언마운트(unmount)라고 한다.
      • 메서드
        • componentWillUnmount : 컴포넌트가 웹상 사라지기 전에 호출 하는 메서드
          • componentDidMount 에서 등록한 이벤트를 여기서 제거 작업을 해야된다.
  •   마지막으로 그림에는 없지만 componentDidCatch 메서드가 v16에서 추가 되었다. 
    • 컴포넌트 렌더링 도중 에러가 발생 했을떄 애플리케이션이 먹통 되지 않고 UI를 보여 줄수 있게 해준다
  • 사용 예시
componentDidCatch(error, info) {
	this.setState({
    	error : ture
    })
    console.log({eror, info});
}

'react' 카테고리의 다른 글

8. React Hooks 란?  (0) 2020.02.03
2. JSX 란  (0) 2019.12.03
1. 리액트 시작  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

2. JSX 란

react 2019. 12. 3. 14:45

1. JSX 란?

JSX는 자바 스크립트 확장 문법이며 XML 비슷 하게 생겼지만 자바스크립트 문법은 아니다.

리액트는 JSX 를 통해 번들링 해서 사용하기 편하게 만들어 졌다고 생각 하면된다.

 

JSX 문법

function App() 
{
	return (
    	<div> 
        	Hellp <b>react</b>
        </div>
    )
}

javascript 문법

function App()
{
	return React.createElement('div',null,'Hello', React.createElement('b',null,'react'));
}

비교 한거와 같이 JSX 문법을 사용 하게 되면 좀더 쉽게 사용 할수 있다. 하지만 JSX를 쓰기 위해서는 몇가지 규칙이 존재한다.

 

1. 컴포넌트에 여러 요소가 있다면 반드시 부로 요소 하나로 감싸야한다. (여러개를 하나의 요소로 감싸서 사용 하는 이유는  Virtual DOM에서 컴포넌트 변화를 감지 해낼떄 효율적으로 사용 하기 위에서 규칙 존재)

function App()
{
	return (
    	1. div 를 사용
        <div> //부모요소로 감싸준다. 
        	<h1>리액트 하이</h1>
            <h2>리액트 하이</h2>
        </div>
        
        2. div 를 생략 하고 사용 한다.
        <> //부모요소로 감싸준다. 
        	<h1>리액트 하이</h1>
            <h2>리액트 하이</h2>
        </>
    )
}

2. JSX 에서 javascript 문법 

improt React from 'react';

function App() 
{
	const name = '리액트';
    return (
    	<>
        	<h1>{name} 하이</h1>
            <h2>잘 작동 하니</h2>
        </>
    )
}

3. if 문 대신 조건부 연산자( {} 안에  () 사용 하는경우는 줄바꿈이 일어나서 코드를 작성 할때 사용) 

improt React from 'react';

function App() 
{
	const name = '리액트';
    return (
    	<>
        1. 
        { name === '리액트' ? (<h1>리액트 입니다.</h1>) : (<h1>리액트 아닙니다.</h1>)};
        2.
        { name === '리액트' ? <h1>리액트 입니다.</h1> : null };
        3. 
        { name === '리액트' && <h1>리액트 입니다.</h1>};
        
        </>
    )
}

4. undefined 를 렌더링 하지 않는다.

improt React from 'react';

function App() 
{
	const name = undefined;
    return (
 		return name;  //오류 발생 
        해결방법
        1. OR 연산자 사용
        return name  || '값이 undefined'입니다.;
        2. JSX 내부에서 undefined 사용 
        return <div>{name}</div>
        3. JSX 내부에 OR 연산자 사용 (name 값이 undefined 일떄 보여줄경우)
        return <div>{name || '리액트'}</div>
    )
}

5. 인라인 스타일은 객체로 반환 (카멜 표기법 사용)

ex ) font-size => fontSize 

 

6. class 대신 className 을 사용

 

7. 꼭닫아야 하는 태그가 존재함 

<input> => <input />

<br> => <br />

<p>  => <p />

 

8. 주석 사용법 

 

평소에 javascript 사용하는 주석 방법

1. // 

2. /* */

 

JSX 주석

1. { /* 주석을 사용한다. */}

 

 

이와 같이 몇가지 규칙이 존재 하지만 규칙 특별하게 어렵지 않고 사용 하다 보면 익숙해 져서 편안하게 사용이 가능 할라꺼라고 생각한다.

 

 

 

 

 

 

'react' 카테고리의 다른 글

8. React Hooks 란?  (0) 2020.02.03
7. 라이플 사이클(Life Cycle) 메서드의이해  (0) 2020.01.22
1. 리액트 시작  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,

1. 리액트 시작

react 2019. 12. 3. 13:30

1. 왜 리액트 인가?

 

javascript 로 비동기 처리를 할라면 업데이트 하는 항목에 따라 어떤 부분을 찾아서 변경할지 규칙을 정하는 작업은 간단 하지만 그 규모가 크면 상담히 복잡 해지고 관리가 제대로 되지 않으면 성능 저하가 올수 있다.

그래서 페이스북 개발팀에서 해결할라고 나온데 리액트 이다.

리액트는 변경할때마다 어떤 변화를 줄지 고민 하는것이 아니라 기존 뷰를 날려 버리고 처음부터 렌더링 하는 방식이다.

이렇게 바뀌면서 구조도 심플해지고 작성 해야할 코드양이 많이 줄이 든다. 

 

2. 리액트의 이해 

 

리액트는 자바 스크립트 라이브러로 사용자 인터페이스를 만드는 사용 한다. mvc,mvw 등 프레임워크와 달리 오직 V(View)만 신경 쓰는 라이브러리 입니다. 

특정 부분이 어떻게 생길지 정하는 선언체(컴포넌트)를 통해 초기 렌러링과 리 렌더링을 한다. 

리액트는  Virtual DOM을 사용 해서 기존 DOM 과 새로운 DOM을 비교 해서 변경이 된 DOM 적용 하게 된다.

절차는 아래와 같다.

 

1. 데이터를 업데이트 하면 전체 UI를 Virtual DOM에 리렌더 합니다.

2. 이전 Virtual DOM에 있던 내용과 현재 내용을 비교 합니다.

3. 바뀐 부분만 실제 DOM에 적용 합니다.

 

이렇게 전체 DOM을 바꾸는게 아니고 변경이 필요한 부분만 교체 하기 떄문에 CPU 과부화를 줄일수 있고 전체 를 변경 할떄 끊김현상을 해결할수 있게 됩니다.

 

3. 환경 설정

 

1. node 와  npm 을 설치

node 다운 로드 경로(LTS버전은 설치)  :  https://nodejs.org/ko/download/

설치후 터미널 창에서 npm --version, node --version 실행후 버전이 나오는지 확인 한다.

C:\work\saramin\react>node --version
v10.16.0

C:\work\saramin\react\hello-react>npm --version
6.9.0

 

node 를 설치 후 아래와 같이 npm 을 설치 해준다

npm install -g create-react-app //npm -g 글로벌로 npm 설치 해준다
create-react-app my-app 

cd my-app  
npm start 

또는 npx 를 사용 할수 있다. npx를 사용 하는걸 추천한다. 그 이유는 npx는 최신 버전에 해당하는 패키지를 설치하여 실행하고, 실행된 이후에 해당 패키지를 제거 해주기 떄문이다.

npx create-react-app my-app

cd my-app
npm start

npm start 를 하면 서버가 실행 되고 http://localhost:3000/와 같은 url 생성 될것이다. url 치고 들어가면 아래 같은 React 기본 페이지가 나왔다면 성공!!!

 

 

'react' 카테고리의 다른 글

8. React Hooks 란?  (0) 2020.02.03
7. 라이플 사이클(Life Cycle) 메서드의이해  (0) 2020.01.22
2. JSX 란  (0) 2019.12.03
블로그 이미지

foglove

개인적으로 공부 하면서 이해가 안가는것들 정리 하거나 책을 보면서 정리 해보는 습관을 가지고 시작한 블로그 입니다.

,