본문 바로가기

WINK-(Web & App)/React.js 스터디

[2025 1학기 React.js 스터디] 이가인 #3주차

반응형

 

1. JSX 이해하기

2. props 사용법

3. 조건부랜더링

4. useState : 동적인 값 관리하기

5. input 상태 관리하기

6. 여러개의 input 상태 관리 

7. 과제 보여주깅


 

JSX

리액트에서 생김새를 정의할 때 사용하는 문법

- 리액트에서 컴포넌트를 만들 때 화면에 보일 구조를 쉽게 표현할 수 있게 도와줌

return <div>안녕하세요</div>;

 

Babel

자바스크립트의 문법을 확장해주는 도구

 

JSX -> JS 변환 제대로 되기위한 규칙

1. 닫혀잇는태그

2. 두 개 이상의 태그는 무조건 하나의 태그로 감싸져 있어야함.

 -> 번거로움 -> Fragment(리액트요소) 사용

 

Fragment 

- <> </>

- 별도의 엘리먼트로 나타나지않음

 

3. JSX 내부에 자바스크립트 변수 보여주기 

{ } 으로 감싸기

 

4. JSX 에서 태그에 style, css 설정하는 법

- html에서와 다름

import React from 'react';
import Hello from './Hello';

function App() {
  const name = 'react';
  const style = {
    backgroundColor: 'black',
    color: 'aqua',
    fontSize: 24, // 기본 단위 px
    padding: '1rem' // 다른 단위 사용 시 문자열로 설정
  }

  return (
    <>
      <Hello />
      <div style={style}>{name}</div>
    </>
  );
}

export default App;

ㄴ style 설정할 때 

 

//App.js
...

return (
    <>
      <Hello />
      <div style={style}>{name}</div>
      <div className="gray-box"></div>
    </>
  );
  
  
//App.css
  .gray-box {
  background: gray;
  width: 64px;
  height: 64px;
}

ㄴ css 설정할 때 

ㄴ class가 아닌 className 임!

 

5. JSX 내부 주석은 { } 사용하지않으면 화면에 보임

 


props 사용법

 

- 다른 컴포넌트에 값을 전달할때 사용

  ㄴ 기본값(props의 모양새)는 전달하는(쓰이는 곳) 컴포넌트에 표기 (App.js)

- 객체 형태로 전달됨 

 

 

//App.js
import React from 'react';
import Hello from './Hello';

function App() {
  return (
    <Hello name="react" color="red"/>
  );
}

export default App;

//Hello.js
import React from 'react';

function Hello(props) {
  return <div style={{ color: props.color }}>안녕하세요 {props.name}</div>
}

//비구조화 할당
function Hello({ color, name }) {
  return <div style={{ color }}>안녕하세요 {name}</div>
}


export default Hello;

ㄴ props여러개면 >>비구조화 할당<< 사용해서 표현 --> 간결하게 작성 가능 

 

 

1. defaultProps 로 기본값 설정

컴포넌트에 props 를 지정하지 않았을 때 기본적으로 사용 할 값을 설정하고 싶다면

//Hello.js
import React from 'react';

function Hello({ color, name }) {
  return <div style={{ color }}>안녕하세요 {name}</div>
}

// 쓰이는 곳에서 props 따로 지정을 안햇을때도
Hello.defaultProps = {
  name: '이름없음'
}

export default Hello;

//App.js
import React from 'react';
import Hello from './Hello';

function App() {
  return (
    <>
      <Hello name="react" color="red"/>
      <Hello color="pink"/>
    </>
  );
}

export default App;

 

 

2. props.children : 컴포넌트 태그 사이에 넣은 값을 조회하고싶을 때 

- Wrapper컴포넌트 만들고, 이 컴포넌트를 태그로 사용했는데, 이 태그 내부에 Hello컴포넌트를 넣었을때

==> hello컴포의 내용이 안보임

//Wrapper.js
import React from 'react';

function Wrapper() {
  const style = {
    border: '2px solid black',
    padding: '16px',
  };
  return (
    <div style={style}>

    </div>
  )
}

export default Wrapper;

//App.js 
import React from 'react';
import Hello from './Hello';
import Wrapper from './Wrapper';

function App() {
  return (
    <Wrapper>
      <Hello name="react" color="red"/>
      <Hello color="pink"/>
    </Wrapper>
  );
}

export default App;

//Wrapper.js
import React from 'react';

function Wrapper({ children }) {
    const style = {
        border: '2px solid black',
        padding: '16px',
    };
    return (
        <div style={style}>
            {children}
        </div>
    )
}

export default Wrapper;

ㄴ 요렇게 wrapper에 props에 {children}을 , return값에도 추가하면 ... 

잘보입니당 !

내부의 내용이 보여지게 하기 위해서는 Wrapper 에서 props.children 을 렌더링해주어야 합니다.

 

이때 랜더링이란 말은 뭘까..?

코드로 작성한 내용을 실제 화면에 보여주는 과정을 ! 말함 (진짜 웹페이지에 보이게 만드는 작업)

📄 코드 → 🖥️ 화면에 보여주는 것 = 렌더링!

 


조건부 랜더링 

조건부 렌더링이란, 특정 조건에 따라 다른 결과물을 렌더링 하는 것을 의미

 

1. 특정 조건에 따라 보여줘야하는 내용이 다를 때  삼항연산자 사용 (가장기본적임)

 

2. 특정 조건이 true면 보여주고 그렇지않다면 숨길 때  : && 연산자 사용

    ㄴ props 값 설정을 생략하면 {true}로 간주함 

 //같은 코드로 해석됨
 <Hello name="react" color="red" isSpecial />
 <Hello name="react" color="red" isSpecial={true} />

 

 

//App.js
import React from 'react';
import Hello from './Hello';
import Wrapper from './Wrapper';


function App() {
  return (
    <Wrapper>
      <Hello name="react" color="red" isSpecial={true}/>
      <Hello color="pink" />
    </Wrapper>
  )
}

export default App;
//Hello.js
import React from 'react';

function Hello({ color, name, isSpecial }) {
  return (
    <div style={{ color }}>
    
    // 1. 삼항연산자
      { isSpecial ? <b>*</b> : null }
      
    // 2. &&연산자
      {isSpecial && <b>*</b>}
    //  isSpecial 이 false 일땐 false 이고, isSpecial이 true 일 땐 <b>*</b> 가 됨
      
      안녕하세요 {name}
    </div>
  );
}

Hello.defaultProps = {
  name: '이름없음'
}

export default Hello;

Hello컴포를 보면 안녕하세요코드 보다 {isSpecial}이 앞에잇어서 앞에 *이 붙여짐 응

😲 JSX 에서 null, false, undefined을 랜더링 하면 아무것도 나타나지 않음 

useState : 동적인 값 관리하기

>> 버튼을 누르면 숫자가 바뀌는 counter컴포넌트 만들기 <<

 

 

1.버튼만들기

 

2.버튼 클릭 시 특정 함수 호출되도록 

 ㄴ 요소에 이벤트설정  (button의 onClick 속성 사용)

on이벤트이름 = { 실행하고싶은함수 }

 

3. useState사용 : 동적인 값 끼얹기 

 ㄴ 이걸 사용하면 컴포넌트에서 상태를 관리 할 수 있다. 

🌟useState
- React가 제공하는 "훅(hook)" 함수

- 상태 만들기 함수라고 보면 됨!!!
- 호출하면 배열을 리턴함 !!  [값, 함수]
const [value, setValue] = useState(기본값);
- 사용 시 컴포넌트에서 상태를 관리 할 수 있다. 
-  상태의 기본값을 파라미터로 넣어서 호출해줌 

 

 

1. 풀어서 쓴 방식 (원리 파악에 도움 됨)

const numberState = useState(0); //useState(0) 호출 결과(배열)를 numState에 저장 --> 배열임 !
const number = numberState[0]; // 현재 값 (0)
const setNumber = numberState[1]; // 값 바꾸는 함수

 

2. 구조 분해 할당 = 배열 비구조화 할당 (간단하고 자주 씀) 

const [number, setNumber] = useState(0);

👉 [현재값, 값바꾸는 함수]  

 

- useState(0)이 배열을 리턴
 - number : 현재 상태

 - setNumber:  Setter함수임 

 

 

🔍 useState(0) vs useState[1] 헷갈림티비..

  • useState(0)는 함수 호출: 0을 기본값으로 해서 상태를 만듦
  • useState[1]은 함수 자체를 배열처럼 쓰려고 하는 거라 잘못된 문법이야 

즉,

  • useState(0) → ✅ 올바른 호출 (상태 생성)
  • useState[1] → ❌ 잘못된 접근 (배열 아님!)

 

//Counter.js
import React, { useState } from 'react';

function Counter() {
  const [number, setNumber] = useState(0);


//화살표함수 사용
  const onIncrease = () => {
    setNumber(number + 1);
  }

  const onDecrease = () => {
    setNumber(number - 1);
  }

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;
//App.js
import React from 'react';
import Counter from './Counter';

function App() {
  return (
    <Counter />
  );
}

export default App;

input 상태 관리하기  

 

button은 onclick 이벤트 

input은 onchange 이벤트

 

ㄴ 이벤트 객체 e를 파라미터로 받아와서 사용 
ㄴ e.target은 이벤트가 발생한 그 input의 DOM을 가르키게 된다. 
ㄴ e.target.value를 조회하면 input에 입력한 값이 무엇인지 알 수 있음
ㄴ input 상태를 관리할 대는 input 태그의 value값도 설정해주는 것이 중요 !!
    ㄴ 상태가 바뀌었을 때 input내용도 업데이트 됨. 

 

 

>>초기화 버튼을 누르면 input 이 이 비워지도록 구현<< 

//InputSample.js
import React, { useState } from 'react'; 

function InputSample() {
  const [text, setText] = useState('');

  const onChange = (e) => {
    setText(e.target.value); 
  };

  const onReset = () => {
    setText('');
  };

  return (
    <div>
      <input onChange={onChange} value={text}  />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: {text}</b>
      </div>
    </div>
  );
}

export default InputSample;

 

코드 설명

function InputSample() {
  const [text, setText] = useState('');

 

  • text: 현재 입력된 값 (처음엔 빈 문자열 '')
  • setText: 입력값을 바꾸는 함수

 

  const onChange = (e) => {
    setText(e.target.value);
  };

 

  • 사용자가 입력창에 뭔가 입력하면 이 함수가 실행됨
  • e.target.value는 입력창에 적힌 글자
  • 그걸 setText()로 상태에 반영해 → 입력이 화면에 반영됨!
  const onReset = () => {
    setText('');
  };

 

 

  • 버튼을 누르면 실행됨
  • 입력값을 빈 문자열로 초기화

 


여러개의 input 상태 관리하기

import React, { useState } from 'react';

function InputSample() {
  const onChange = (e) => {
  };

  const onReset = () => {
  };


  return (
    <div>
      <input placeholder="이름" />
      <input placeholder="닉네임" />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        이름 (닉네임)
      </div>
    </div>
  );
}

export default InputSample;

이렇게만 했을 시 

초기화 버튼 눌러도 안됨!!!

 

//InputSample.js

import React, { useState } from 'react';

function InputSample() {
  const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });

  const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출

  const onChange = (e) => {
    const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
    setInputs({
      ...inputs, // 기존의 input 객체를 복사한 뒤
      [name]: value // name 키를 가진 값을 value 로 설정
    });
  };

  const onReset = () => {
    setInputs({
      name: '',
      nickname: '',
    })
  };


  return (
    <div>
      <input name="name" placeholder="이름" onChange={onChange} value={name} />
      <input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname}/>
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}

export default InputSample;

 

 

코드 설명

const [inputs, setInputs] = useState({
  name: '',
  nickname: ''
});

 

  • inputs라는 객체 상태를 만들어서 name, nickname 두 값을 한꺼번에 관리함
const onChange = (e) => {
  const { value, name } = e.target;
  setInputs({
    ...inputs,
    [name]: value
  });
};

 

🌟 젤 중요한 개념 !!!!!!

  • e.target은 이벤트가 발생한 input 태그
  • 거기서 name과 value를 꺼냄
  • setInputs()는 기존의 상태를 복사하고,
    • ...inputs = 기존 값 유지
  • 거기서 name이라는 key에 value를 넣음
    • inputs["nickname"] = "홍길동" 이런 느낌

👉 그래서 하나의 onChange로 두 input을 처리할 수 있음 

const onReset = () => {
  setInputs({
    name: '',
    nickname: '',
  })
};

 

  • 버튼을 누르면 두 input 모두 빈칸으로 초기화함
<input name="name" placeholder="이름" onChange={onChange} value={name} />
<input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname}/>
  • name 속성 덕분에 onChange에서 어떤 input이 바뀌었는지 구분 가능
  • name, placeholder, onChange, value 은 input의 속성임!!!!! 
  • 입력한 값은 상태값에 따라 화면에 반영(랜더링)

과제 보여드릴게여 꽤나 열시미햇어요 

버튼 hover, active 안주면 죽는병걸림

 

 


끗끘끗 꼴등은 아니겟져 ㅎㅎ?? 감사합니자.

반응형