๐Ÿ‘ฉ๐Ÿปโ€๐ŸŒพ

[JS/React] 1๏ธโƒฃ ๊ฐ„๋‹จํ•œ ์ผ๊ธฐ์žฅ ๋งŒ๋“ค๊ธฐ ๋ณธ๋ฌธ

Language/JavaScript

[JS/React] 1๏ธโƒฃ ๊ฐ„๋‹จํ•œ ์ผ๊ธฐ์žฅ ๋งŒ๋“ค๊ธฐ

์ฅฌ์Šค์ด 2023. 4. 13. 16:25
728x90

ํฌ์ŠคํŒ…์„ ํ•˜๊ธฐ์— ์•ž์„œ ์—ฌ๋‹ด ํ•˜๋‚˜๋ฅผ ์–˜๊ธฐํ•˜์ž๋ฉด,

๋”๋ณด๊ธฐ

์ธํ”„๋Ÿฐ์— ๋ฆฌ์•กํŠธ ๊ฐ•์˜๋“ค์ด ๊ฝค ๋งŽ๊ณ  ๊ฐ๊ฐ์˜ ๊ฐ•์˜๋“ค์€ ํ•ด๋‹น ๊ฐ•์˜๋ฅผ ์ˆ˜๊ฐ•ํ•˜๋ฉด ์ตœ์†Œ 1๊ฐœ์—์„œ ๋งŽ๊ฒŒ๋Š” 4-5๊ฐœ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์™„์„ฑํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค. ๋‚ด๊ฐ€ ์ˆ˜๊ฐ• ์ค‘์ธ ๋ฆฌ์•กํŠธ ๊ฐ•์˜๋Š” '๊ฐ์ • ์ผ๊ธฐ์žฅ' ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ ์ˆ˜๋งŽ์€ ๊ฐ•์˜๋“ค ์ค‘ ๋‚ด๊ฐ€ ์ด ๊ฐ•์˜๋ฅผ ์„ ํƒํ•œ ์ด์œ ๊ฐ€ ์ข€ ํ™ฉ๋‹นํ•˜๋‹ค.
๋Œ€ํ•™๊ต 1ํ•™๋…„ ๋•๊ฐ€ ์•ฑ์Šคํ† ์–ด ์ธ๊ธฐ ์œ ๋ฃŒ ์•ฑ์— 'MOODA'๋ž€ ๊ฐ์ •์„ ๊ธฐ๋กํ•ด์„œ ์ผ๊ธฐ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์•ฑ์ด ์žˆ์—ˆ๋‹ค. ์•ฑ ์•„์ด์ฝ˜๊ณผ ์ƒ์„ธ ํ™”๋ฉด ์‚ฌ์ง„์„ ๋ดค์„ ๋•Œ, UI๊ฐ€ ์ƒ๋‹นํžˆ ์•„๊ธฐ์ž๊ธฐ(์•„๊ธฐ์ž๊ธฐํ•œ ๊ฑฐ์— ๋งˆ์Œ์ด ์•ฝํ•œ ํŽธ)ํ•˜์—ฌ ๊ตฌ๋งคํ•˜๊ฒŒ ๋˜์—ˆ๊ณ  2๋…„ ๋™์•ˆ์€ ๊ฝค ์ž˜ ์‚ฌ์šฉํ•œ ๊ฑฐ ๊ฐ™๋‹ค.
์—ฌํŠผ, ๊ทธ๋ž˜์„œ ์กธ์—…์ž‘ํ’ˆ์—์„œ ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ผ์„œ ์ฒ˜์Œ ์‚ฌ์šฉํ•ด๋ณด๋Š” ํ„ฐ๋ผ ๋ฆฌ์•กํŠธ ๊ฐ•์˜๋ฅผ ์ฐพ์•„๋ณด๊ณ  ์žˆ์—ˆ๊ณ , ํ•ด๋‹น ๊ฐ•์˜๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด ์ˆ˜์—…์„ ๋“ค์œผ๋ฉด ๋‚˜ ๊ฐ™์€ ์ดˆ์งœ๋„ MOODA ๊ฐ™์€ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค์–ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค๋‹ˆ๋ผ๋Š” ์‹ ๊ธฐํ•œ ๋งˆ์Œ์ด ๋“ค์–ด์„œ ์„ ํƒํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค...ใ…Ž(๋ฆฌ๋ทฐ๋„ ๋งŽ๊ธด ํ–ˆ๋‹ค...)

~ํ˜น์‹œ MOODA UI๋ฅผ ๊ถ๊ธˆํ•ดํ• ๊นŒ ์‹ถ์–ด์„œ ์ฒจ๋ถ€~

 

๋ณธ๋ก ์œผ๋กœ ๋Œ์•„์™€์„œ, ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ์ผ๊ธฐ์žฅ ํ‹€์„ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์— ๋Œ€ํ•ด ์ž‘์„ฑํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. (์ดํ›„์— ๊ธฐ๋Šฅ๋“ค์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ๊ธ€์— ์ด์–ด์„œ ํฌ์ŠคํŒ…์„ ์—…๋กœ๋“œํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.)

 

 

๐Ÿ“Œ ๊ตฌํ˜„ํ•  ์ผ๊ธฐ์žฅ์˜ ๊ตฌ์กฐ

์ƒ๋‹จ - ์ž‘์„ฑ์ž

์ค‘์•™ - ์ผ๊ธฐ๋‚ด์šฉ

ํ•˜๋‹จ - ๊ฐ์ •์ง€์ˆ˜

์ด๋ ‡๊ฒŒ 3๊ฐœ์˜ input์„ ์ž…๋ ฅ ๋ฐ›์•„์„œ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ, ์ €์žฅ ์„ฑ๊ณตํ–ˆ๋‹ค๋Š” ์•Œ๋ฆผ์ด ๋œธ

 

 

 

 

๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป ์ „์ฒด ์ฝ”๋“œ

๋”๋ณด๊ธฐ
import React, { useState, useRef } from "react";

const DiaryEditor = () => {

  const [state, setState] = useState({
    author: "",
    content: "",
    emotion: 1,
  });

  const authorInput = useRef(); // focus()๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Input์ฐฝ์— ์ ‘๊ทผ
  const contentInput = useRef();

  const handleChangeState = (e) => {
    setState({
      ...state,
      [e.target.name]: e.target.value,
    });
  };

  const handleSubmit = () => {
    if (state.author.length < 1) {
      authorInput.current.focus();
      return;
    }
    if (state.content.length < 5) {
      contentInput.current.focus();
      return;
    }
    alert("์ผ๊ธฐ ์ €์žฅ ์„ฑ๊ณต");
  };
  
  return (
    <div className="DiaryEditor">
      <h2>์˜ค๋Š˜์˜ ์ผ๊ธฐ</h2>
      <div>
        <input
          ref={authorInput}
          name="author"
          value={state.author}
          onChange={handleChangeState}
        ></input>
      </div>
      <div>
        {/* ์—ฌ๋Ÿฌ ์ค„ ์ž…๋ ฅ ๊ฐ€๋Šฅ */}
        <textarea
          ref={contentInput}
          name="content"
          value={state.content}
          onChange={handleChangeState}
        ></textarea>
      </div>
      <div>
        <span>์˜ค๋Š˜์˜ ๊ฐ์ •์ ์ˆ˜ : </span>
        <select
          name="emotion"
          value={state.emotion}
          onChange={handleChangeState}
        >
          <option value={1}>1</option>
          <option value={2}>2</option>
          <option value={3}>3</option>
          <option value={4}>4</option>
          <option value={5}>5</option>
        </select>
      </div>
      <div>
        <button onClick={handleSubmit}>Save</button>
      </div>
    </div>
  );
};

export default DiaryEditor;
const [state, setState] = useState({
    author: "",
    content: "",
    emotion: 1,
  });

  const authorInput = useRef(); // focus()๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Input์ฐฝ์— ์ ‘๊ทผ
  const contentInput = useRef();

โฌ†๏ธ ์ „์ฒด ์ฝ”๋“œ์—์„œ ํ•ด๋‹น ์ฝ”๋“œ๋Š” input์œผ๋กœ ๋“ค์–ด์˜ค๋Š” ์ž…๋ ฅ๊ฐ’๋“ค์˜ ์ดˆ๊ธฐ๊ฐ’๊ณผ ์ดํ›„์— focus ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ ์–ธํ•ด ๋†“์€ ๋ณ€์ˆ˜๋“ค์ž…๋‹ˆ๋‹ค.

 

์ด์ œ, handleChangeState() ํ•จ์ˆ˜์™€ handleSubmit() ํ•จ์ˆ˜๋ฅผ ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

const handleChangeState = (e) => {
    setState({
      ...state,
      [e.target.name]: e.target.value,
    });
  };

โฌ†๏ธ ์ด ํ•จ์ˆ˜๋Š” ์ž‘์„ฑ์ž, ์ผ๊ธฐ๋‚ด์šฉ, ๊ฐ์ •์ง€์ˆ˜๊ฐ€ input์œผ๋กœ ์ž…๋ ฅ์ด ๋“ค์–ด์™”์„ ๋•Œ onChange ์ด๋ฒคํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

spread ์—ฐ์‚ฐ์ž๋กœ useState๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ •ํ•œ ์ดˆ๊ธฐ๊ฐ’๋“ค์„ ์‚ฌ์šฉํ•˜๋˜, ์ž…๋ ฅ ๋“ค์–ด์˜จ ๊ฐ์ฒด์˜ value๊ฐ’์€ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค.

const handleSubmit = () => {
    if (state.author.length < 1) {
      authorInput.current.focus();
      return;
    }
    if (state.content.length < 5) {
      contentInput.current.focus();
      return;
    }
    alert("์ผ๊ธฐ ์ €์žฅ ์„ฑ๊ณต");
  };

โฌ†๏ธ ์ด ํ•จ์ˆ˜๋Š” ์ž‘์„ฑ์ž๋ฅผ ์ž…๋ ฅํ•˜๋Š” ์นธ์ด๋‚˜ ์ผ๊ธฐ ๋‚ด์šฉ์„ ์ž…๋ ฅํ•˜๋Š” ์นธ์— ์ผ์ • ๊ธ€์ž์ˆ˜๋ฅผ ์ฑ„์šฐ์ง€ ์•Š๊ณ  Save ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ, onChange ์ด๋ฒคํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

์ด๋•Œ, useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜์˜€์œผ๋ฏ€๋กœ '๋ณ€์ˆ˜๋ช…'.current.focus();๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ focus ๊ธฐ๋Šฅ์„ ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ธ€์ž์ˆ˜๋ฅผ ๋ชจ๋‘ ๋งŒ์กฑํ•œ๋‹ค๋ฉด ์•Œ๋ฆผ์ฐฝ์ด ๋œจ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ฐ๊ฐ์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์€ ์–ด๋ ต์ง€ ์•Š์œผ๋ฏ€๋กœ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค๐Ÿ˜Š

728x90
Comments