React Hook

이용만·2023년 8월 9일
0

useEffect

import React from 'react'
import { useEffect, useState } from 'react'

function App() {

  const [value, setValue] = useState('');
  useEffect(function(){
    console.log(`hello useEffect : ${value}`);

    //clean up
    return () => {
      console.log('나 사라져요!');
    }
    //[] : 의존성 배열 ; 값이 변경되었을 때 useEffect 시작
  }, [value]);

  return <div>
    <input type='text' value={value} onChange={(event) => {
      setValue(event.target.value);
    }}></input>
  </div>
}

export default App

useEffect : 화면에서 렌더링 되고 나서 실행되는 함수
clean up : 어떤 컴포넌트가 화면에서 사라졌을 때 실행되는 함수


useRef

  • 설정된 ref 값은 컴포넌트가 계속해서 렌더링 되어도 unmount 전까지 값을 유지
  • 저장공간용으로 활용 가능하다. 단, state와는 다르게 state변화가 일어나면 렌더링이 되질 않는다.
    1. state는 리렌더링이 꼭 필요한 값을 다룰 때 쓰면 된다.
  1. ref는 리렌더링을 발생시키지 않는 값을 저장할 때 사용한다.
  • DOM, 렌더링 되자마자 특정 input이 focusing돼야 한다면 useRef를 사용한다.
  • 렌더링 되기 전까지 값을 유지
import React from 'react'
import { useState } from 'react'
import { useRef } from 'react'

function App() {
  const [count, setCount] = useState(0);

  const countRef = useRef(0);

  const stateButton = function(){
    setCount(count + 1);
  };

  const refButton = function(){
    countRef.current++;
    console.log(countRef);
  };

  return (
    <>
      <div style={{
        border: "1px solid black",
        margin: "10px",
        padding: "10px",
      }}>
        State 영역입니다. {count} <br/>
        <button onClick={stateButton}>state 증가</button>
      </div>

      <div style={{

        border: "1px solid red",
        margin: "10px",
        padding: "10px",
        
      }}>
        ref 영역입니다.{countRef.current} <br />
        <button onClick={refButton}>ref 증가</button>
      </div>
    </>
  )
}

export default App
  • useRef 를 통해 focus
import React, { useEffect, useRef } from 'react'


//로그인 화면에 왔을때 자동으로 로그인 input에 포커싱이 되어야함
function App() {

  const idRef = useRef('');

  const passwordRef = useRef('');

  //화면이 렌더링 될 때, 어떤 작업을 하고 싶다 : useEffect
  useEffect(() => {
    passwordRef.current.focus();
  },[]);

  return (
    <>
     <div>
      아이디 : <input type='text' ref={idRef}/>
     </div>
     <div>
      비밀번호 : <input type='password'ref={passwordRef}/>
     </div>
    </>
  )
}

export default App
  • 심화
import React, { useEffect, useRef, useState } from 'react'

function App() {

  const idRef = useRef('');
  const passwordRef = useRef('');

  const [id, setId] = useState('');

  useEffect(() => {
    idRef.current.focus();
  }, []);

  useEffect(() => {
    if(id.length >=10){
      passwordRef.current.focus();
    }
  }, [id]);

  return (
    <>
      <div>
        아이디 : <input 
        value={id}
        onChange={(event) => {
          setId(event.target.value);
        }}
        type='text' ref={idRef}></input>
      </div>
      
      <div>
        비밀번호 : <input type='password' ref={passwordRef}></input>
      </div>
    </>
  )
}

export default App

useContext : useContext hook을 통해 쉽게 전역 데이터를 관리

  • FamilyContext.js
import { createContext } from "react";

export const FamilyContext = createContext(null);
  • GrandFather.jsx
import React from 'react'
import Father from './Father';
import { FamilyContext } from '../context/FamilyContext';

//FG -> Child한테 어떤 정보를 알려주고 Cild가 그 내용을 출력하도록 
function GrandFather() {
  const houseName = '스파르타';
  const pocketMoney= 10000;

  return (
      <FamilyContext.Provider 
      value={{
        houseName: houseName,
        pocketMoney: pocketMoney,
      }}>
        <Father></Father>
      </FamilyContext.Provider>
  )
}

export default GrandFather
  • Father.jsx
import React from 'react'
import Child from './Child';

function Father() {
  return (
    <Child></Child>
  )
}

export default Father
  • Child.jsx
import React, { useContext } from 'react'
import { FamilyContext } from '../context/FamilyContext'

function Child() {

  const style = {
    color: 'tomato',
    fontWeight: '900',
  }

  const data = useContext(FamilyContext);
  console.log('data', data);

  return (
    <div>우리 집안은 <br/>
      <span style={style}>{data.houseName}이고</span> <br/>
      용돈은 <span style={style}>{data.pocketMoney} 원 </span> 받아요.
      </div>
  )
}

export default Child

최적화(React momo, useCallback, useMemo)

  • memo : 컴포넌트를 캐싱
  • useCallback : 함수를 캐싱
  • useMemo : 값을 캐싱

부모 컴포넌트가 바뀌게 되면 바뀌지도 않은 자식 컴포넌트들이 렌더링 될 필요가 없는데
바뀌는 경우에 사용이 된다.

import React, { useState } from 'react'
import Box1 from './components/Box1';
import Box3 from './components/Box3';
import Box2 from './components/Box2';

function App() {
  console.log('App.jsx렌더링 되었습니다.');
  const [count, setCount] = useState(0);

  const onPlusButton = function(){
    setCount(count+1);
  }

  const onMinusButton = () => {
    setCount(count-1);
  }
  

  return (
    <>
    <h3>카운트 예제입니다.</h3>
    <p>현재 카운트 : {count}</p>
    <button onClick={onPlusButton}>+</button>
    <button onClick={onMinusButton}>-</button>

    <div style={{
      display: 'flex'
    }}>
      <Box1></Box1>
      <Box2></Box2>
      <Box3></Box3>
    </div>
    </>
    
  )
}

export default App
  • Box1.jsx
import React from 'react'

function Box1() {

  console.log("Box1 컴포넌트 렌더링");

  return (
    <div style={{
      width: '100px',
      height: '100px',
      backgroundColor: 'tomato',
      color: 'white',
      margin: '30px',
    }}>Box1</div>
  )
}

export default React.memo(Box1);
  • Box2.jsx
import React from 'react'

function Box2() {

  console.log("Box2 컴포넌트 렌더링");

  return (
    <div style={{
      width: '100px',
      height: '100px',
      backgroundColor: 'skyblue',
      color: 'white',
      margin: '30px',
    }}>Box2</div>
  )
}

export default React.memo(Box2)
  • Box3.jsx
import React from 'react'

function Box3() {

  console.log("Box3 컴포넌트 렌더링");

  return (
    <div style={{
      width: '100px',
      height: '100px',
      backgroundColor: 'pink',
      color: 'white',
      margin: '30px',
    }}>Box3</div>
  )
}

export default React.memo(Box3)
profile
성장하는 개발자가 되고자 합니다.

1개의 댓글

comment-user-thumbnail
2023년 8월 9일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기