반응형

일반 HTML에서 DOM 요소에 일늠을 달 때 id를 사용한다.

<div id="my-element"></div>

이렇게 요소에 id를 달면 CSS에서 특정 id에 특정 스타일을 적용하거나 자바스크립트에서 해당id를 가진 요소를 찾아 작업할 수 있다.

 

HTML에서 id를 사용하는 것처럼, 리액트 내부에서 DOM에 이름을 다는 방법이 있는데 그것이 ref(reference)의 개념이다.

 

 

※리액트 컴포넌트 안에서도 id를 사용할 수 있지만, HTML에서 DOM의 id는 유일해야하는데, 컴포넌트가 여러번 사용되면 중복 id가 생기니 잘못된 사용이다. ref는 전역적으로 작동하지않고, 컴포넌트 내부에서만 작동하기 때문에 문제가 발생하지 않는다.

 

ref는 어떤 상황에서 사용해야 할까?

ref는 "특정 DOM을 꼭 직접적으로 건드려야 할 때" 사용한다. 순수 자바스크립트 혹은 jQuery로 만든 웹사이트에서 input을 검증할 때는 다음과 같이 작성한다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Example</title>
  <style>
    .success {
      background-color: lightgreen;
    }
    .failure {
      background-color: lightcoral;
    }
  </style>
  <script>
    function validate() {
      var input = document.getElementById('password');
      input.className='';
      if(input.value==='0000') {
        input.className='success';
      } else {
        input.className='failure';
      }
    }
  </script>
</head>
<body>
  <input type="password" id="password"></input>
  <button onclick="validate()">Validate</button>
</body>
</html>

리액트에서는 이런 작업이 굳이 DOM에 접근하지 않아도 state로 구현할 수 있다. src디렉토리에 ValidationSample.css와 ValidationSample.js를 만들어보자

 

ValidationSample.css

.success {
  background-color: lightgreen;
}

.failure {
  background-color: lightcoral;
}

 

ValidationSample.js

import React, { Component } from 'react';
import './ValidationSample.css';

class ValidationSample extends Component {
  state = {
    password: '',
    clicked: false,
    validated: false,
  };

  handleChange = e => {
    this.setState({
      password: e.target.value,
    });
  };

  handleButtonClick = () => {
    this.setState({
      clicked: true,
      validated: this.state.password === '0000',
    });
  };

  render() {
    return (
      <div>
        <input
          type="password"
          value={this.state.password}
          onChange={this.handleChange}
          className={this.state.clicked ? (this.state.validated ? 'success' : 'failure') : ''}
        />
        <button onClick={this.handleButtonClick}>Validate</button>
      </div>
    );
  }
}

export default ValidationSample;

 

ValidationSample.js를 보면 input의 onChane이벤트가 발생했을 때, handleChange를 호출하여 password 값을 업데이트하고, button에서 onClick 이벤트가 발생했을 때 handleButtonClick을 호츌하여 clicked값을 참으로 설정하고 validated 값을 검증 결과로 설정했다.

 

input의 className은 버튼을 누르기 전에는 빈 문자열, 버튼을 누른 후에 검증이 성공하면 success, 실패하면 failure로 설정했다. 이에따라 input의 색상이 변한다.

 

App 컴포넌트에서 ValidationSample 컴포넌트를 불러와 렌더링해본다.

import React, { Component } from 'react';
import ValidationSample from './ValidationSample';

class App extends Component {
  render() {
    return <ValidationSample />;
  }
}

export default App;

 

원하는 결과가 잘 나타나는 것을 확인할 수 있다. 이렇게 자바스크립트에서는 DOM에 접근해야했던 기능을 리엑트에서는 state를 사용하여 구현할 수 있다. 하지만 state만으로 해결할 수 없는 기능들이있다


예)

1. 특정 input에 포커스주기

2. 스크롤 박스 조작하기

3. Canvas 요소에 그림 그리기

 

ref 사용

ref를 사용하는 방법은 두 가지이다.

콜백 함수를 통한 ref 설정

ref를 만드는 가장 기본적인 방법은 콜백 함수를 사용하는 것이다. ref를 달고자 하는 요소에 콜백 함수 ref를 props로 전달해주면 된다. 이 콜백 함수는 ref값을 파라미터로 받고, ref를 컴포넌트의 멤버 변수로 설정해준다.

<input
  ref={ref => {
    this.input = ref;
  }}
/>

 

createRef를 통한 ref설정

리액트에 내장되어 있는 createRef라는 함수를 사용해 ref를 만들 수도있다. 이 기능은 리액트 v16.3부터 도입되었다.

import React, { Component } from 'react';

class RefSample extends Component {
  input = React.createRef();

  handleFocus = () => {
    this.input.current.focus();
  };

  render() {
    return (
      <div>
        <input ref={this.input} />
      </div>
    );
  }
}

export default RefSample;

createRef를 사용하여 ref를 만들려면 먼저 컴포넌트 내부에서 멤버 변수로 React.createRef()를 담아준다 그리고 해당 멤버 변수를 ref를 달고자 하는 요소에 ref props로 넣어주면된다.

 

이렇게 설정하고 나중에 DOM에 접근하려면 this.input.current 처럼 뒤에 .current를 넣어주어야한다.

 

ref로 버튼 클릭 시 input으로 포커스 이동 구현

위에서 만들었던 ValidationSample에서 Validate 버튼 클릭 시 input으로 포커스가 넘어가도록 코드를 수정해본다

 

input에 ref 달기

배운 대로 input 요소에 ref를 정용한다.

 

ValidationSample.js

(...)
    <input>
      ref={(ref) => this.input=ref}
      (...)
    />

 

버튼 onClick 이벤트 수정

버튼에서 onClick 이벤트가 발생할 때 input에 포커스를 주도록 코드를 수정한다. ref를 적용했기 때문에 이제 this.input으로 DOM을 접근할 수 있으므로, 일반 DOM의 함수를 사용할 수 있다

 

ValidationSample.js

handleButtonClick = () => {
  this.setState({
    clicked: true,
    validated: this.state.password === '0000',
  });
  this.input.focus();
};

이제 코드를 실행해보면 버튼 클릭시 포커스가 input요소로 넘어가는 것을 볼 수 있다.

 

컴포넌트에 ref 달기

리액트에서는 컴포넌트에도 ref를 달 수 있다. 이렇게 하면 컴포넌틍 내부에 있는 DOM을 컴포넌트 외부에서 사용할 수 있다.

 

사용법

<MyComponent
  ref={ref => {
    this.myComponent = ref;
  }}
/>

이렇게 한 이후에 myComponent.handleClick, myComponent.input 등으로 컴포넌트 내부 ref(DOM 요소)에 접근할 수 있게된다.

 

스크롤 박스 예제

이제 스크롤 박스 예제를 만들어본다

 

ScrollBox.js

import React, { Component } from 'react';

class ScrollBox extends Component {
  render() {
    const style = {
      border: '1px solid black',
      height: '300px',
      width: '300px',
      overflow: 'auto',
      position: 'relative',
    };

    const innerStyle = {
      width: '100%',
      height: '650px',
      background: 'linear-gradient(white, black)',
    };

    return (
      <div
        style={style}
        ref={ref => {
          this.box = ref;
        }}
      >
        <div style={innerStyle} />
      </div>
    );
  }
}

export default ScrollBox;

 

App 컴포넌트에서는 기존 ValidationSample을 지우고 ScrollBox 컴포넌트를 렌더링한다.

 

App.js

import React, { Component } from 'react';
import ScrollBox from './ScrollBox';

class App extends Component {
  render() {
    return (
      <div>
        <ScrollBox />
      </div>
    );
  }
}

export default App;

 

코드를 저장하면, 웹 브라우저에 스크롤 박스가 잘 렌더링된다.

 

이제 버튼을 추가하고 버튼을 클릭했을 때, 스크롤 박스의 스크롤바를 맨 아래쪽으로 내리는 메소드를 만들어 본다 . 이 기능을 구현하기 위해 DOM 노드가 가진 값을 사용한다.

 

  • scrollTop : 세로 스크롤바 위치
  • scrollHeight : 스크롤이 있는 박스 안의 div 높이
  • clientHeight : 스크롤이 있는 박스의 높이

스크롤을 내려야 볼 수 있는 박스 내부의 긴 콘텐츠 > scrollHeight

긴 콘텐츠를 스크롤바로 감싸는 박스 > clientHeight

 

스크롤바의 위치 scrollTop은 0부터 (박스 내부의 긴 콘텐츠 - 스크롤바로 감싸고 있는 바깥의 박스)의 크기 값을 가진다. (바깥의 박스가 300이고 내부의 콘텐츠가 650이라면 스크롤바의 위치가 0~350)

 

따라서 스크롤바를 맨 아래쪽으로 내리려면 scrollHeight에서 clientHeight를 빼면된다

 

ScrollBox.js

 

import React, { Component } from 'react';

class ScrollBox extends Component {
  scrollToBottom = () => {
    const { scrollHeight, clientHeight } = this.box;
    this.box.scrollTop = scrollHeight - clientHeight;
  };
  render() {
    const style = {
      border: '1px solid black',
      height: '300px',
      width: '300px',
      overflow: 'auto',
      position: 'relative',
    };

    const innerStyle = {
      width: '100%',
      height: '650px',
      background: 'linear-gradient(white, black)',
    };

    return (
      <div
        style={style}
        ref={ref => {
          this.box = ref;
        }}
      >
        <div style={innerStyle} />
      </div>
    );
  }
}

export default ScrollBox;

 

ScrollBox 컴포넌트에서, this.box로 스크롤바가 있는 박스 DOM에 접근할 수 있고, scrollToBottom 이라는 메소드가 이 DOM에 접근하여 스크롤바의 위치 scrollTop를 맨 아래로 변경한다.

 

이렇게 만들고 나서 부모 컴포넌트인 App 컴포넌트에서 ScrollBox 컴포넌트에 ref를 달고, 버튼을 만든 다음 onClick이벤트에 ScrollBox 컴포넌트의 메소드인 scrollToBottom을 실행하도록 한다.

 

App.js

import React, { Component } from 'react';
import ScrollBox from './ScrollBox';

class App extends Component {
  render() {
    return (
      <div>
        <ScrollBox ref={ref => (this.ScrollBox = ref)} />
        <button onClick={() => this.ScrollBox.scrollToBottom()}>맨 밑으로</button>
      </div>
    );
  }
}

export default App;

맨 밑으로 버튼을 눌렀을 때 스크롤바가 맨 밑으로 이동하는 것을 확인할 수 있다.

 

그런데 주의할 점이 있는데, button요소에 onClick이벤트를 등록할때, onClick={this.scrollBox.scrollToBottom}으로 작성하는 것이 문법상으로 틀린것은 아니다. 하지만 컴포넌트가 처음 렌더링 될 때는 this.scrollBox값이 undefined이다. (ref 등록이 콜백함수이므로)

 

따라서 화살표 함수 문법으로 새로운 함수를 만들고, 그 내부에서 this.scrollBox.scrollToBottom매소드를 실행하면 버튼을 누를 때, (이미 한번 렌더링을 거쳐 this.scrollBox 를 설정한 시점) this.scrollBox.scrollToBottom 값을 읽어와서 실행하므로 오류가 발생하지 않는다.

 

 

정리

컴포넌트 내부에서 DOM에 직접 접근해야 할 때는 ref를 사용한다. 하지만 ref를 사용하지 않고 원하는 기능을 구현할 수 있는지를 반드시 고려해야한다.

 

서로 다른 컴포넌트끼리 데이터를 교류할 때 ref를 사용하는 것이라고 오해할 수 있는데, 그렇게 하는 것은 애플리케이션의 구조를 꼬이게 만들 수 있는 위험한 방법이다. 따라서 데이터를 교륳라 때는 언제나 부모 - 자식 흐름으로 교류하는 것이 좋다.

 

참조

김민준님의 리액트를 다루는 기술을 참조하여 작성한 글입니다.

반응형

'FrontEnd > React' 카테고리의 다른 글

리엑트 공부 재시작 !  (0) 2023.01.22
[React] Modal창 열기  (0) 2023.01.22
React - Node 연동  (0) 2023.01.22
[React] UseEffect  (0) 2023.01.01
[React] 이벤트 핸들링  (0) 2022.10.14
반응형
리엑트의 이벤트 시스템

사용자가 웹 브라우저에서 DOM요소들과 상호 작용하는 것을 이벤트(event)라고 한다.

리액트의 이벤트 시스템은 웹 브라우저의 HTML 이벤트와 인터페이스가 동일하기 때문에 사용법이 꽤 비슷하다.
하지만 주의해야 할 몇 가지 사항이 있다.

 

이벤트 사용 시 주의사항

1. 이벤트 이름은 카멜표기법으로 작성

     HTML에서는 onclick으로 작성하지만 리액트에서는 카멜 표기법으로 onClick으로 작성해야한다
2. 이벤트에는 함수 형태의 값을 전달

    HTML에서 이벤트를 설정할 때 ""안에 실행할 코드를 넣었지만, 리액트에서는 함수 형태의 객체를 전달한다. 애로우(화     살표)함수 문법을 사용하거나 혹은 외부에 미리 함수를 만들어서 전달하기도한다.

3. DOM요소에만 이벤트를 설정할 수 있다.

    div, button, input, form, span 등의 DOM요소에는 이벤트를 설정할 수 있지만, 직접만든 리액트 컴포넌트에는 이벤트를     자체적으로 설정할 수 없다.

<MyComponent onClick={doSomethine}>

    이 코드는 이름이 onClick인 props를 컴포넌트에 전달할 뿐이다.

    컴포넌트에 자체적으로 이벤트를 설정할 수는 없지만, 전달받은 props를 컴포넌트 내부의 DOM이벤트로

    설정할 수는있다.

<div onClick={this.props.onClick}>{/* ... */}</div>

리액트에서 지원하는 다양한 이벤트 종류는 아래의 링크를 통해 확인할 수 있다.

 

합성이벤트

 

합성 이벤트(SyntheticEvent) – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

 

이벤트 핸들리 예제

컴포넌트 생성 및 불러오기

src 디렉토리에 EventPractice.js 파일을 만들고 App 컴포넌트에서 불러와 렌더링한다.

 

EventPractice.js

import React, { Component } from 'react';

class eventPractice extends Component {
    render() {
        return (
            <div>
                <h1>Event Practice</h1>          
            </div>
        );
    }
}

export default eventPractice;           <h1>Event Practice</h1>

 

App.js

import React from 'react';
import EventPractice from './eventPractice';

const App = () => {
  return <EventPractice/>
}

export default App;

onChange 이벤트 핸들링하기

EventPractice 컴포넌트에 input 요소를 렌더링하는 코드와 해당 요소에 onChange 이벤트를 설정하는 코드를 작성한다.

 

import React, { Component } from 'react';

class eventPractice extends Component {
    render() {
        return (
            <div>
                <h1>Event Practice</h1>        
                <input
                 tpye="text"
                 name="message"
                 placeholder="type something"
                 onChange={e =>{
                    console.log(e);
                 }}
                 />  
            </div>
        );
    }
}

export default eventPractice;

React 실행 후 콘솔창을 킨 후 input요소에 텍스트를 입력해본다.

콘솔에 SyntheticzEvent 라는 객체가 나타나는 것을 볼 수 있는데, 이 객체는 웹 브라우저의 네이티브 이벤트를 감싸는 객체로, 이벤트 함수의 파라미터(예제 코드에서는 e)로 접근할 수 있다.

 

네이티브 이벤트와 인터페이스가 같으므로, 순수 JS에서 HTML이벤트를 다룰 때와 똑같이 사용하면되지만, 네이티브 이벤트와 달리 이벤트가 끝나면 이벤트가 초기화 되므로 정보를 참조할 수 없기 때문에ㅡ 비동기적으로 이벤트 객체를 참조해야 한다면 e.persist()함수를 호출해 주어야 한다

 

이제 state에 input값을 담아보도록 한다. state 초기값을 설정하고 이벤트 핸들링 함수 내부에서 this.setState 메소드를 호출하여 state를 업데이트 한다

 

import React, { Component } from 'react';

class eventPractice extends Component {
    state = {
        message:'',
    }
    render() {
        return (
            <div>
                <h1>Event Practice</h1>        
                <input
                 tpye="text"
                 name="message"
                 placeholder="type something"
                 value={this.state.message}
                 onChange={e =>{
                    this.setState({
                        message: e.target.value,
                    })
                 }}
                 />
                 <button
                 onClick={ () => {
                    alert(this.state.message);
                    this.setState({
                        message:'',
                    });
                 }}  
                 >
                 submit
                 </button>
            </div>
        );
    }
}

export default eventPractice;

input에 아무거나 입력 후 버튼을 누르면 해당 값이 alert으로 호출되는것을 확인 할 수 있다.

 

임의 메소드 만들기

현재의 코드는 이벤트에 실행할 함수를 렌더링 메소드 내부에 만들어서 전달해주고 있다. 이 방법 대신 함수를 미리 만들어 전달하면 가독성을 높일 수 있다.

import React, { Component } from 'react';

class EventPractice extends Component {
  state = {
    message: '',
  };

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  handleChange(e) {
    this.setState({
      message: e.target.value,
    });
  }

  handleClick() {
    alert(this.state.message);
    this.setState({
      message: '',
    });
  }

  render() {
    return (
      <div>
        <h1>Event Practice</h1>
        <input
          type="text"
          name="message"
          placeholder="type something"
          value={this.state.message}
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>Submit</button>
      </div>
    );
  }
}

export default EventPractice;

여기서 주의해야할 점은 this 바인딩이다. this는 함수가 어디서 호출되는지에 따라 결정된다.

클래스의 임의 메소드가 특정 HTML요소의 이벤트로 등록되는 과정에서 메도스와 this의 관계가 끊어지게된다.

 

따라서 this를 컴포넌트 자신으로 가르키게 하기 위해서는 메소드를 this와 바인딩하는 작업이 필요하고, 현재 코드에서는 constructor 함수 내부에서 함수를 바인딩하고 있다. 메소드 바인딩은 이렇게 생성자 메소드에서 하는 것이 정석이다. 새 메소드를 만들때마다 constuctor도 수정해야하기 때문이다.

하지만 클래스형 컴포넌트에서 public class fields 문법을 사용하여 화살표 함수로 메소드를 구현하면, 좀 더 편하게 작성할 수 있다. 화살표 함수의 this는 부모함수의 this를 상속받는데 JS에서 클래스는 함수로 구현되어 있기 때문에 this는 컴포넌트 자신이 되므로 bind(this)를 하지 않아도 된다.

import React, { Component } from 'react';

class EventPractice extends Component {
  state = {
    message: '',
  };

  handleChange = e => {
    this.setState({
      message: e.target.value,
    });
  };

  handleClick = () => {
    alert(this.state.message);
    this.setState({
      message: '',
    });
  };

  render() {
    return (
      <div>
        <h1>Event Practice</h1>
        <input
          type="text"
          name="message"
          placeholder="type something"
          value={this.state.message}
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>Submit</button>
      </div>
    );
  }
}

export default EventPractice;

이 문법은 실험적인 문법으로 바벨을 설정해주어야 하는데 Create-React-App으로 만든 프로젝트는 이 문법이 기본적으로 설정되어 있으므로 사용 가능하다.

 

input 여러개 다루기

이제 input 값을 state에 넣는 방법을 알아보았다. input이 여러개일때 방법을 알아보자. 메소드를 여러개 만들어 해결할 수 있지만, event 객체를 활용하면 더 쉽게 처리할 수 있다

onChange 이벤트 핸들러에서 e.target.name은 해당 input의 name을 가리킨다. 이값을 이용해 state를 설정하면 더 쉽게 해결할 수 있다.

import React, { Component } from 'react';

class EventPractice extends Component {
  state = {
    username: '',
    message: '',
  };

  handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value,
    });
  };

  handleClick = () => {
    alert(this.state.username + ': ' + this.state.message);
    this.setState({
      username: '',
      message: '',
    });
  };

  render() {
    return (
      <div>
        <h1>Event Practice</h1>
        <input
          type="text"
          name="username"
          placeholder="User name"
          value={this.state.username}
          onChange={this.handleChange}
        />
        <input
          type="text"
          name="message"
          placeholder="type something"
          value={this.state.message}
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>Submit</button>
      </div>
    );
  }
}

export default EventPractice;
handleChange = e => {
  this.setState({
    [e.target.name]: e.target.value,
  });
};

이 코드를 보면 e.target.name을 []로 감싸는데 이렇게 객체안에서 key를 []로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key값으로 사용된다.

 

onKeyPress 이벤트 핸들링

키를 눌렀을 때 발생하는 KeyPress 이벤트를 처리해본다. 두 번째 인풋에서 Enter키를 눌렀을때 handleCllck 메소드를 호출하도록 코드를 추가한다.

import React, { Component } from 'react';

class EventPractice extends Component {
  state = {
    username: '',
    message: '',
  };

  handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value,
    });
  };

  handleClick = () => {
    alert(this.state.username + ': ' + this.state.message);
    this.setState({
      username: '',
      message: '',
    });
  };

  handleKeyPress = e => {
    if (e.key === 'Enter') {
      this.handleClick();
    }
  };

  render() {
    return (
      <div>
        <h1>Event Practice</h1>
        <input
          type="text"
          name="username"
          placeholder="User name"
          value={this.state.username}
          onChange={this.handleChange}
        />
        <input
          type="text"
          name="message"
          placeholder="type something"
          value={this.state.message}
          onChange={this.handleChange}
          onKeyPress={this.handleKeyPress}
        />
        <button onClick={this.handleClick}>Submit</button>
      </div>
    );
  }
}

export default EventPractice;

함수형 컴포넌트로 구현해 보기

이제 클래스형 컴포넌트로 작성했던 EventPractice 컴포넌트를 함수형 컴포넌트로 바꾸어본다.

import React, { useState } from 'react';

const EventPractice = () => {
  const [username, setUsername] = useState('');
  const [message, setMessage] = useState('');
  const onChangeUsername = e => setUsername(e.target.value);
  const onChangeMessage = e => setMessage(e.target.value);
  const onClick = () => {
    alert(username + ': ' + message);
    setUsername('');
    setMessage('');
  };
  const onKeyPress = e => {
    if (e.key === 'Enter') {
      onClick();
    }
  };

  return (
    <div>
      <h1>Event Practice</h1>
      <input
        type="text"
        name="username"
        placeholder="User name"
        value={username}
        onChange={onChangeUsername}
      />
      <input
        type="text"
        name="message"
        placeholder="type something"
        value={message}
        onChange={onChangeMessage}
        onKeyPress={onKeyPress}
      />
      <button onClick={onClick}>Submit</button>
    </div>
  );
};

export default EventPractice;

기능이 이전과 같이 동작하는지 확인해본다.

 

위의 함수형 컴포넌트 코드에서는 e.target.name을 사용하지 않고 onChange 관련 함수를 따로 만들었다. 하지만 input의 개수가 많아질수록 불편해지므로 e.target.name을 활용하는 것이 더 좋을 수 있다.

 

import React, { useState } from 'react';

const EventPractice = () => {
  const [form, setForm] = useState({
    username: '',
    message: '',
  });
  const { username, message } = form;
  const onChange = e => {
    const nextForm = {
      ...form,
      [e.target.name]: e.target.value,
    };
    setForm(nextForm);
  };
  const onClick = () => {
    alert(username + ': ' + message);
    setForm({
      username: '',
      message: '',
    });
  };
  const onKeyPress = e => {
    if (e.key === 'Enter') {
      onClick();
    }
  };

  return (
    <div>
      <h1>Event Practice</h1>
      <input
        type="text"
        name="username"
        placeholder="User name"
        value={username}
        onChange={onChange}
      />
      <input
        type="text"
        name="message"
        placeholder="type something"
        value={message}
        onChange={onChange}
        onKeyPress={onKeyPress}
      />
      <button onClick={onClick}>Submit</button>
    </div>
  );
};

export default EventPractice;

정리

리액트에서 이벤트를 다루는 것은 순수 JS또는 jQuery를 사용한 웹 애플리케이션에서 이벤트를 다루는 것과 비슷하다. 따라서 기존 HTML DOM Event를 알고 있다면 리액트의 컴포넌트 이벤트도 쉽게 다룰 수 있다.


 

 

참조

김민준님의 리액트를 다루는 기술 참조

반응형

'FrontEnd > React' 카테고리의 다른 글

리엑트 공부 재시작 !  (0) 2023.01.22
[React] Modal창 열기  (0) 2023.01.22
React - Node 연동  (0) 2023.01.22
[React] UseEffect  (0) 2023.01.01
ref: DOM에 이름달기  (0) 2022.10.14

+ Recent posts