๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
JavaScript/React

[React] ์ปดํฌ๋„ŒํŠธ ์•Œ์•„๋ณด๊ธฐ

by soy๋ฏธ๋‹ˆ 2021. 10. 26.

 

 

 

 

 

โœ ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น

 

const { name, favoriteNumber, children } = this.props; // ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น
const { number, fixedNumber } = this.state;            // ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น

 

this.props ๊ฐ€ ๊ฐ€์ง„ name, favoriteNumber, children ๊ฐ’์„ { name, favoriteNumber, children } ์— ๋„ฃ์–ด์ค€๋‹ค.

 

 

 

โœ constructor ์—†์ด state ์ดˆ๊นƒ๊ฐ’ ์ง€์ •ํ•˜๊ธฐ

 

class Counter extends Component {
	state = {
    	number: 0,
        fixedNumber: 0
    }
    render(){
    	const {number, fixedNumber} = this.state;
        return ( ... );
    }
}

 

 

 

 

โœ this.setState ์— ๊ฐ์ฒด ๋Œ€์‹  ํ•จ์ˆ˜ ์ธ์ž ์ „๋‹ฌํ•˜๊ธฐ

 

onClick={() => {
	this.setState({ number: number + 1 });
    this.setState({ number: this.state.number + 1 });
}}

 

์ด ๊ฒฝ์šฐ ํด๋ฆญ์„ ํ–ˆ์„ ๋•Œ ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋‘ ๋ฒˆ ๋ฐœ์ƒํ•  ๊ฒƒ ๊ฐ™์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ์ˆซ์ž๊ฐ€ ํ•œ ๋ฒˆ๋งŒ ์ฆ๊ฐ€ํ•œ๋‹ค. this.setState ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ”๋กœ state ๊ฐ’์ด ๋ฐ”๋€Œ์ง€๋Š” ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด this.setState ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ์ฒด ๋Œ€์‹  ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

 

 

 

<button onClick={() => {
	this.setState(prevState => {
    	return{
        	number: prevState.number + 1
        }
    });
    // ์œ„ ์ฝ”๋“œ์™€ ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํ•œ๋‹ค.
    // ์ฐจ์ด์ ์€ ์•„๋ž˜ ์ฝ”๋“œ๋Š” ํ•จ์ˆ˜์—์„œ ๋ฐ”๋กœ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.
    this.setState(prevState => ({
    	number: prevState.number + 1
    }));
}}></button>

 

์—ฌ๊ธฐ์„œ prevState ๋Š” ๊ธฐ์กด ์ƒํƒœ์ด๊ณ , props๋Š” ํ˜„์žฌ ์ง€๋‹ˆ๊ณ  ์žˆ๋Š” props ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

 

 

 

 

โœ useState ์•Œ์•„๋ณด๊ธฐ

 

const [message, setMessage] = useState('');

 

useState ํ•จ์ˆ˜์˜ ์ธ์ž์—๋Š” ์ƒํƒœ์˜ ์ดˆ๊นƒ๊ฐ’์„ ๋„ฃ์–ด ์ฃผ๋Š”๋ฐ, ๋ฐ˜๋“œ์‹œ ๊ฐ์ฒด์ผ ํ•„์š”๋Š” ์—†๋‹ค. ๋ฌธ์ž์—ด, ์ˆซ์ž, ๊ฐ์ฒด, ๋ฐฐ์—ด ๋“ฑ ๊ฐ’์˜ ํ˜•ํƒœ๋Š” ์ž์œ ์ด๋‹ค. ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฐฐ์—ด์ด ๋ฐ˜ํ™˜๋˜๋Š”๋ฐ ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋Š” ํ˜„์žฌ ์ƒํƒœ์ด๊ณ , ๋‘ ๋ฒˆ์งธ ์›์†Œ๋Š” ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ์–ด์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ด๋ฅผ Setter ํ•จ์ˆ˜๋ผ๊ณ  ํ•œ๋‹ค. ๋ฐฐ์—ด ๋น„๊ตฌ์กฐํ™” ํ• ๋‹น์„ ํ†ตํ•ด ์ด๋ฆ„์„ ์ž์œ ๋กญ๊ฒŒ ์„ค์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

 

import {useState} from 'react';

const Counter = () => {
	const [value, setValue] = useState(0);
    
    return(
    	<div>
        	<p>
            ํ˜„์žฌ ์นด์šดํ„ฐ ๊ฐ’์€ <b>{value}</b>์ž…๋‹ˆ๋‹ค.
            </p>
            <button onClick={()=>setValue(value+1)}>๋”ํ•˜๊ธฐ</button>
            <button onClick={()=>setValue(value-1)}>๋นผ๊ธฐ</button>
        </div>
    )
}

export default Counter

 

โœ ref ์•Œ์•„๋ณด๊ธฐ

 

ReactDOM.render(<App />, document.getElementById('root'));

 

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;

 

import { Component } from "react";

class ScrollBox extends Component {
  scrollToBottom = () => {
    const { scrollHeight, clientHeight } = this.box;
    this.box.scrollTop = scrollHeight - clientHeight;
    console.log(this.box, scrollHeight, clientHeight, this.box.scrollTop);
  };

  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;

 

ํŠน์ • DOM ์— ์ž‘์—…์„ ํ•ด์•ผ ํ•  ๋•Œ, DOM ์„ ์ง์ ‘์ ์œผ๋กœ ๊ฑด๋“œ๋ ค์•ผ ํ•  ๋•Œ ref ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ref ๋Š” ๋ฆฌ์•กํŠธ ๋‚ด์—์„œ id ์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•œ๋‹ค. ์ฆ‰, ์œ„์˜ return() ๋‚ด์— ์žˆ๋Š” <div> ์š”์†Œ๋Š” ์•ž์œผ๋กœ this.box ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค. ์ด๋ฆ„์€ this.box ๋ง๊ณ  this.bigBox ๋ผ๋“ ๊ฐ€ this.cup ์ด๋ผ๋“ ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•œ ref ์„ค์ •

ref ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ref ๋ฅผ ๋‹ฌ๊ณ ์ž ํ•˜๋Š” ์š”์†Œ์— ref ๋ผ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ props ๋กœ ์ „๋‹ฌํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ref ๊ฐ’์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ ๋ฐ›๋Š”๋‹ค.

 

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

 

์—ฌ๊ธฐ์„œ this.input ์€ input ์š”์†Œ์˜ DOM ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

 

 

 

 

 

โœ key ์•Œ์•„๋ณด๊ธฐ

 

key ๋Š” ์ปดํฌ๋„ŒํŠธ ๋ฐฐ์—ด์„ ๋ Œ๋”๋งํ–ˆ์„ ๋•Œ ์–ด๋–ค ์›์†Œ์— ๋ณ€๋™์ด ์žˆ์—ˆ๋Š”์ง€ ์•Œ์•„๋‚ด๋ ค๊ณ  ์‚ฌ์šฉํ•œ๋‹ค. key ๊ฐ€ ์—†์„ ๋•Œ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋น„๊ตํ•˜๋ฉด์„œ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜์ง€๋งŒ key ๊ฐ€ ์žˆ์œผ๋ฉด ์ด ๊ฐ’์„ ์‚ฌ์šฉํ•ด์„œ ์–ด๋–ค ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚ฌ๋Š”์ง€ ๋น ๋ฅด๊ฒŒ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

 

import React from "react";

const IteraationSample = () => {
  const names = [" ๋ˆˆ์‚ฌ๋žŒ", "์–ผ์Œ", "๋ˆˆ", "๋ฐ”๋žŒ"];
  const nameList = names.map((name, index) => <li key={index}>{name}</li>);
  return <ul>{nameList}</ul>;
};

export default IteraationSample;

 

map ํ•จ์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์ธ์ˆ˜์ธ index ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๊ณ ์œ ํ•œ ๊ฐ’์ด ์—†์„ ๋•Œ๋งŒ index ๋ฅผ key ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. index ๋ฅผ key ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฐ์—ด์ด ๋ณ€๊ฒฝ๋  ๋•Œ ํšจ์œจ์ ์œผ๋กœ ๋ฆฌ๋ Œ๋”๋งํ•˜์ง€ ๋ชปํ•œ๋‹ค.

 

 

 

 

 

 

โœ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€/์‚ญ์ œ ๊ตฌํ˜„ํ•˜๊ธฐ

 

import { useState } from "react";

const IteraationSample = () => {
  const [names, setNames] = useState([
    { id: 1, text: "๋ˆˆ์‚ฌ๋žŒ" },
    { id: 2, text: "์–ผ์Œ" },
    { id: 3, text: "๋ˆˆ" },
    { id: 4, text: "๋ฐ”๋žŒ" },
  ]);
  const [inputText, setInputText] = useState("");
  const [nextId, setNextId] = useState(5); // ์ถ”๊ฐ€ํ•  ๋ฐ์ดํ„ฐ์˜ ์ธ๋ฑ์Šค๊ฐ€ 5๋ถ€ํ„ฐ ์‹œ์ž‘

  const onChange = (e) => {
    setInputText(e.target.value);
    console.log(e.target.value);
  };
  
  // ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•˜๊ธฐ : ๋ฐฐ์—ด ๋‚ด์žฅ ํ•จ์ˆ˜ concat ์‚ฌ์šฉ
  const onClick = () => {
    const nextNames = names.concat({
      id: nextId, // ๋‹ค์Œ๋ฒˆ ์ธ๋ฑ์Šค์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ธฐ
      text: inputText, // ์ž…๋ ฅํ•œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ˆ text๋กœ inputText ์ง€์ •
    });
    setNextId(nextId + 1); // ๋‹ค์Œ ์ธ๋ฑ์Šค๋ฅผ ์œ„ํ•ด 1 ์˜ฌ๋ฆฌ๊ธฐ
    console.log(nextId + 1);
    setNames(nextNames); // ๋ฆฌ์ŠคํŠธ์— ์ด๋ฒˆ์— ์ถ”๊ฐ€ํ•˜ ๋‚ด์šฉ ์ถ”๊ฐ€
    console.log(nextNames);
    setInputText(""); // inputText ๋น„์šฐ๊ธฐ
  };

// ๋ฐ์ดํ„ฐ ์‚ญ์ œํ•˜๊ธฐ : ๋ฐฐ์—ด ๋‚ด์žฅ ํ•จ์ˆ˜ filter ์‚ฌ์šฉ
  const onRemove = (id) => {
    const nextNames = names.filter((name) => name.id !== id);
    setNames(nextNames);
  };

// ๋ฐ์ดํ„ฐ ๋ณด์—ฌ์ฃผ๊ธฐ & ๋”๋ธ”ํด๋ฆญ ์‹œ ์‚ญ์ œ
  const namesList = names.map((name) => (
    <li key={name.id} onDoubleClick={() => onRemove(name.id)}>
      {name.text}
    </li>
  ));
  
  return (
    <>
      <input value={inputText} onChange={onChange} />
      {/* ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ถ”๊ฐ€ */}
      <button onClick={onClick}>์ถ”๊ฐ€</button>
      <ul>{namesList}</ul>
    </>
  );
};
export default IteraationSample;

 

 

 

 

์›น ์‹คํ–‰ ํ™”๋ฉด

 

 

 

 

 

 

 

 

๋„์„œ [๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ ] ์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

๋Œ“๊ธ€