React - #5 useRef

임다이·2023년 12월 11일

React

목록 보기
6/11

useRef

  • 특정 요소를 선택해서 그 요소에 변화를 주고 싶을 때, 바닐라 script에서는 getElementById, querySelector ... 등의 문법을 사용했다.
    -React에서도 특정 요소에 접근해야 할 일이 종종 발생함
    ex) 특정 input에만 focus, 클릭 시 요소의 사이즈 변경, ...etc

※ 주의사항
use~ (리액트 훅)를 사용할 때는 특정 함수 안에 선언문이 들어있으면 안된다.


  • Context API

  • Component Tree

→ 위에서 아래로 - 단방향 데이터 흐름(one-way reactive data flow)


단방향 데이터 흐름(one-way reactive data flow)

Q. 단방향으로 데이터를 관리 할 때 장점?

→ 자식요소에서 부모요소로 데이터를 바로 전달 할 수 없다.





  • Context API
    context를 이용하면 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다.

  • Context 란?

    • 리액트 컴포넌트 간에 값을 전역적으로 공유할 수 있게 해주는 기능

    • 우리에게는 데이터를 주고받는 props가 있는데 왜 context를 써야하는가?

      A. props로만 데이터를 전달하면 깊숙하게 위치한 컴포넌트에 데이터를 전달하는 경우
      여러번 연달아서 props를 설정하게 됨 => 불편하고, 실수가 잦음
      이러한 현상을 props drilling 이라고 부른다.

      그래서 우리는 context로 전역적으로 데이터를 관리한다.

[Context 만드는 순서]
1) context 파일을 만들어준다.

  • createContext
  • 꼭! export 해주기

2) context를 사용할 공간에 import {context} 해주기!

3) context Provider로 감싸주기

  • Provider 안에 value라는 속성
  • value 안에 우리가 전달하고자 하는 데이터, 저장하고자 하는 데이터 등등을 넣는다.

복습
  • 화면 단에서 바로 반응하는 변할 수 있는 수?
    → state

  • 여러 개의 태그를 나만의 조합으로 묶어주는
    → component

** 대문자로 반드시 시작할 것


  • useRef - 내가 어떤 특정 요소에 접근하고 싶을 때

  • 하위 → 상위 컴포넌트로 데이터 전송 X

  • function을 통해 데이터를 주고 받았음!


  • var와 let의 차이점? (면접 질문으로 많이 나옴)
    호이스팅 끌어올리다!
    let은 호이스팅 현상이 일어나지만, TDZ라는 죽은 공간에 함수, 변수 데이터를 보관

실습

  • Ex07.jsx
import React, {useRef} from 'react'
import './App.css';

const Ex07 = () => {

    /**
     주의사항!
     use~ (리액트 훅)를 사용할 때는
     특정 함수 안에 선언문이 들어있으면 안된다
    */
    const divRef = useRef();

    /** 원하는 값으로 사이즈를 변경시켜주는 함수 */
    const changeSize = (size) => {
        console.log('divRef', divRef.current)
        divRef.current.style.width = size + "px";
        divRef.current.style.height = size + "px";
    };
    const ckBtn = (e) => {
        console.log('ck', e.target.innerText);
        if(e.target.innerText === "작게") {
            changeSize(100)
        }else if(e.target.innerText === "크게") {
            changeSize(300)
        }else {
            changeSize(200)
        }
    };

  return (
    <div>
        <button onClick={ckBtn}>작게</button>
        <button onClick={ckBtn}>원본</button>
        <button onClick={ckBtn}>크게</button>

        <div className='square' ref={divRef}/>
    </div>
  )
}

export default Ex07
  • App.css
.square {
  background-color: pink;
  width: 200px;
  height: 200px;
  margin: 2%;
}

  • 작게
  • 원본
  • 크게

  • Ex08.jsx
import React, {useEffect, useRef} from 'react'

const Ex08 = () => {

    const iframeSrc = useRef();
    const inputText = useRef();

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


    const changePdf = (name)=>{
        iframeSrc.current.src = `pdf/pdfFile${name}.pdf`
    }


     const ckBtn = () => {
        console.log('inputText', inputText.current.value)
        if(inputText.current.value === "첫번째"){
            changePdf("1");
        }else{
            changePdf("2");
        }
     };

  return (
    <div>
        <input type='text' ref={inputText}/>
        <button onClick={ckBtn}>pdf 변경</button>
        <iframe 
            width="100%"
            height="90%"
            ref={iframeSrc}>
        </iframe>
    </div>
   )
}

export default Ex08

  • 처음에
  • 첫번째 입력
  • 두번째 입력

profile
노는게 제일 좋아~!

0개의 댓글