React

[새싹 프론트엔드] 리액트 이벤트 핸들링

hyriver(강화영) 2022. 12. 4. 00:53

1. 리액트에서의 이벤트를 사용할때 주의 사항

이벤트이름 = {이벤트값}

1) 이벤트이름은 카멜표기법으로 작성한다. ex) onClick, onChange 등

2) 이벤트의 값으로 함수형태를 전달 (자바스크립트 코드X)

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

- div, button, input, form 등에만 이벤트 설정 가능하고, 직접 만든 컴포넌트에는 불가

 

 

 

2. 이벤트에 매개변수를 전달하기 위해서는 익명함수를 통해서만 매개변수가 전달된다

- function 함수

<button onClick={ function () {changeFont('10px')} }> 글자크기변경 </button>

- 화살표 함수

<button onClick={ () => {changeFont('10px')} }> 글자크기변경 </button>

 

 

 

3. onChange 이벤트

 

onChange이벤트 : input창에 입력했을 때 콘솔과 브라우저에 입력값(변경된 value) 출력

 

import React, { useState } from "react";

function EventonChange() {
  const [message, setMessage] = useState("onChange 이벤트");
  // 메세지의 초기값 : onChange 이벤트

  function printConsole(e) {
    // 이벤트 객체의 value를 console에 출력하는 함수
    // input이 변하면(onChange) printConsole 함수가 실행된다.
    console.log(e.target.value);
  }

  function onChange(e) {
    // 이벤트 객체의 value로 message변수를 변경하는 setMessage를 수행한다.
    setMessage(e.target.value);
  }

  return (
    <div>
      <h1>{message}</h1>
      
      <input
        type="text"
        name="msg1"
        placeholder="내용을 입력하세요"
        onChange={printConsole}
        // 이 input창은 입력 시 콘솔에 출력
      />

      <input
        type="text"
        name="msg2"
        placeholder="내용을 입력하세요"
        onChange={onChange}
        // 이 input창은 입력 시 브라우저 출력 값 변경
      />
    </div>
  );
}

export default EventonChange;

 

 

 

input 태그가 여러 개인 경우

: input 각각에 name을 설정하고 name을 키로, 입력한 value를 값으로 하는 새로운 객체(nextForm)를 만든다.

setForm함수를 이용하여 form값을 nextForm으로 변경한다.

 

* 스프레드 연산으로 form의 기존 값을 가져오고 그 다음에 'key:value' 를 적어주면 해당 키값이 변경된다.

 

* [e.target.키이름] : 이벤트 객체의 키 -> 키를 들고오려면 대괄호를 사용한다.

 

import React, { useState } from "react";

function MultiInput() {
  const [form, setForm] = useState({ username: "", message: "" });

  function onChange(e) {
    // 객체인 form을 바꾸는 setForm을 수행하는 함수
    const nextForm = { ...form, [e.target.name]: e.target.value };
    // nextForm은 기존 form 객체를 스프레드 연산으로 가져오고,
    // 그 다음에 이벤트 객체인 input의 name값을 '키'로,
    // input의 value를 '값'으로 저장하는 새로운 객체이다.

    //객체의 키에 접근하려면 대괄호를 사용한다.
    setForm(nextForm);
    // 이 새로운 객체 nextForm으로 form을 변경한다
    // =input에 새로운 값을 넣으면 form이 변한다
  }
  return (
    <div>
      <h1>사용자이름 : {form.username}</h1>
      <h1>내용 : {form.message}</h1>
      <input
        type="text"
        name="username"
        placeholder="사용자 이름"
        onChange={onChange}
      />
      <input
        type="text"
        name="message"
        placeholder="내용을 입력하세요"
        onChange={onChange}
      />
    </div>
  );
}

export default MultiInput;

 

 

 

form태그를 이용한 데이터 전송

: input type=submit으로 만든 버튼을 클릭하면 form안의 input의 value를 전송시킨다.

submit의 기본 동작은 데이터를 전송하고 페이지를 새로고침하는 것인데,

데이터를 전송하다가 페이지가 새로고침되면 데이터 전송이 되지않고

입력했던 input의 내용이 사라진다.

그래서 submit의 기본 동작을 막아주는 preventDefault() 를 사용하면 페이지가 새로고침 되는 것을 막아준다.

 

import React, { useState } from "react";

function NameForm() {
  const [form, setForm] = useState("");

  function updateValue(e) {
    setForm(e.target.value);
    //onSubmit은 form태그에 붙여줘야 input에 받은 값을 데이터로 전송할 수 있다.
  }

  function submitHandler(e) {
    console.log(`submit으로 받은 데이터 : ${form}`);
    e.preventDefault();
    //html태그의 기본동작을 막는다
    //submit의 기본 동작은 데이터를 전송하고, 페이지 새로고침인데
    //페이지 새로고침하는 것을 막는다 -> 새로고침으로 데이터 전송이 도중에 끊어진다
  }

  return (
    <div>
      <form onSubmit={submitHandler}>
        <h1>이름 : {form}</h1>
        <input type="text" onChange={updateValue} />
        <input type="submit" value="전송" />
      </form>
    </div>
  );
}

export default NameForm;

 

 

 

select 태그를 이용한 데이터 전송 - 처음부터 특정 값이 선택되게 하기

 

import React, { useState } from "react";

function Select() {
  const [select, setSelect] = useState("banana");
  //select의 기본값은 banana
  //select 태그의 value가 select 즉, banana가 되고,
  //value가 banana인 옵션이 선택된다.

  function updateValue(e) {
    setSelect(e.target.value);
  }

  function submitHandler(e) {
    console.log(`submit으로 받은 데이터 : ${select}`);
    e.preventDefault();
  }
  return (
    <div>
      <form onSubmit={submitHandler}>
        <h1>선택한 과일 : {select} </h1>
        <select value={select} onChange={updateValue}>
          <option value="apple">사과</option>
          <option value="mango">망고</option>
          <option value="banana">바나나</option>
          <option value="watermelon">수박</option>
        </select>
        <input type="submit" value="전송" />
      </form>
    </div>
  );
}

export default Select;

 

 

 

4. 이미지 추가하기

* 이미지 파일 추가

- import 사용

import 변수명 from '이미지 경로';

<img src = { 변수명 }>

 

- require() 사용

<img src = { require('이미지 경로') }>

 

- public 디렉토리 내부에 이미지 (public/images/apple.png)

<img src = "/images/apple.png">

 

- 외부 서버 이미지

const url = "www.naver.com";

<img src = { url }>

 

 

 

select 태그 이용하여 옵션 선택 시 이미지 띄우기

 

import React, { useState } from "react";
//select태그 + 이미지

const SelectImage = () => {
  const selectList = ["apple", "mango", "banana", "watermelon"];
  const [select, setSelect] = useState("");

  function updateValue(e) {
    //option 태그의 value로 select값 변경
    setSelect(e.target.value); // select : "" -> images/apple.png

    // 이벤트 타겟 왜 option인지 select 아니고?
    // select 맞는데 'select value = option value' 이다
  }

  return (
    <div>
      <h1>선택한 과일 : {select} </h1>
      {/* 이 select도 과일.png로 나온다 */}
      <select value={select} onChange={updateValue}>
        {/* select value = option value */}
        {/* select가 변경이 되면 updateValue함수 실행 */}

        {selectList.map((fruit) => (
          <option value={`/images/${fruit}.png`}>{fruit}</option>
          // map로 selectList 배열 안의 모든 요소들을 돌면서 값을 (/images/${fruit}.png 이렇게) 변경하여 새로운 배열을 생성 + 옵션명 변경

          //옵션의 value 왜 필요한지? 이미지는 <img>에서 나오고 src에서 value값을 받는게 아니라 select값을 받는데..?
          //option의 value가 select의 value가 되고, updateValue함수에서 setSelect를 실행하여 select를 변경한다.
          //변경된 select가 img의 src에 들어간다

          //map은 새로운 배열이 생성되는건데 어디서?
          //새롭게 생성은 되지만 변수 지정을 안해줬으므로...그냥 생성된거
        ))}
      </select>
      <img src={select} width="150px" height="150px" alt="파일없음" />
    </div>
  );
};

export default SelectImage;

 

 

 

체크 박스 선택 시 이벤트 핸들러 사용하여 부모 컨포넌트에서 받은 값으로 전체 합계 변경

 

import React, { useState } from "react";

const Checkbox = (props) => {
  // props를 통해 부모 컨포넌트에서 값을 받을 수 있다.
  const { cap, shose, bag } = props;
  const [total, setTotal] = useState(0);
  // total : 합계, 합계의 초기값은 0

  //체크박스의 체크 유무에 따라 total값을 변경해주는 함수
  const changeHandler = (checkbox) => {
    if (checkbox.checked) {
      // 체크박스가 체크되면 setTotal은 checkbox의 value(=하위 컴포넌트로부터 받은 값(props))을 prevState에 더해준다
      // prevState : 이전상태값
      // setTotal(익명함수: 이전상태값에 value 더하기) 함수로 total 값 변경
      setTotal((prevState) => prevState + parseInt(checkbox.value));
    }
    else {
      //체크 해제 시 prevState에서 value 빼서 total 값 변경
      setTotal((prevState) => prevState - parseInt(checkbox.value));
    }
  };

  return (
    <div>
      <input
        type="checkbox"
        value={cap}
        // 이 값이 상위 컴포넌트로부터 받은 값(props)
        onChange={(e) => changeHandler(e.target)}
        // 값이 변경되면(onChange) changeHandler 함수 실행
      />
      모자 1만원
      <br />
      <input
        type="checkbox"
        value={shose}
        onChange={(e) => changeHandler(e.target)}
      />
      신발 3만원
      <br />
      <input
        type="checkbox"
        value={bag}
        onChange={(e) => changeHandler(e.target)}
      />
      가방 8만원
      <br />
      <p>합계 : {total} </p>
    </div>
  );
};

export default Checkbox;

 

새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 7주차 블로그 포스팅