본문 바로가기
CodeIt_Sprint/React_초급

(9)React_초급_JSX 문법6 : props객체의 Children 프로퍼티, useState 사용하기

by 코잼민 2024. 11. 23.

● Defalut 상황

○ App.js + index.js

//App.js
import Dice from './Dice';

function App() {
  return (
    <>
      <Dice color="blue" num={4} />
    </>
  )
}

export default App;


//index.js
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <>
    <App/>
  </>
);

■ 주사위 위에 "던지기" , "처음부터" 라는 버튼을 Button 컴포넌트 태그로 만들어 보기

● 개념1_ props객체의 children 프로퍼티 이용해서 Button 컴포넌트 만들기

=> src폴더에 "Button.js" 생성 => 아래와 같은 코드 작성

- 일반적인 Button 컴포넌트 (props 객체의 text 속성 이용)

//Button.js

// props객체의 속성 "text" 라는 속성 생성, 속성값 대입하면, 버튼안에 text 출력
function Button(text)
{
	return <button>{text}</button>
}

export default Button; //외부에서 Button 컴포넌트 사용할 수 있도록 함

- Children 속성

//Button.js

// props객체의 속성 "text" 라는 속성 생성, 속성값 대입하면, 버튼안에 text 출력
// 대신 {children} 매개인자
function Button({children})
{
	return <button>{children}</button>
}

export default Button; //외부에서 Button 컴포넌트 사용할 수 있도록 함

=> 따라서 , children 속성 정의

컴포넌트에서 태그의 textContent값 설정 때 이용하는 문법

- 외부에서 Button 컴포넌트 사용

○ App.js

import Button from './Button';
import Dice from './Dice';

function App() {
  return (
    <>
      <div>
      	//속성값 따로 대입 없이, textContent 대입 사용
        <Button>던지기</Button>
        <Button>처음부터</Button>
      </div>
      <Dice color="blue" num={4} />
    </>
  )
}

export default App;

◎ 이론문제1 :

아래 코드를 참고해서 보기 중 Profile 컴포넌트에 전달한 props를 올바르게 활용하는 코드를 선택해 주세요.

○ App.js

import Profile from './Profile';

function App() {
  return (
    <>
      <Profile name="Jerry" msg="배움을 좋아하고 성장을 즐깁니다" role="Software Engineer"/>
      <Profile name="Peter" msg="상상을 현실로 만드는 걸 좋아해요." role="Product Manager"/>
      <Profile name="Haillie" msg="즐겁고 힙하게!" role="BX Designer"/>
      <Profile name="Joy" msg="인생은 재밌게" role="Video Designer"/>
    </>
  );
}

export default App;

- 해석 :

<Profile> 컴포넌트의 속성 "name" , "msg", "role" 을 태그에서 직접 속성값 대입

=> Profile.js의 function Profile () 에서는 props객체의 프로퍼티 props.name , props.msg, props.role 로 사용될 것이다.

● 답1 : 

○ Profile.js

function Profile(props) {
  return (
	<div>
    	<h1>{props.name}</h1>
        <h2>{props.role}</h2>
        <p>{props.msg}</p>
    </div>
  );
}

export default App;

● 답2 : 

○ Profile.js

function Profile({name, role , msg}) {
  return (
	<div>
    	<h1>{name}</h1>
        <h2>{role}</h2>
        <p>{msg}</p>
    </div>
  );
}

export default App;

 

=> 결론  : 두 코드는 같게 작동된다.

 

● 개념2_ useState 사용하기

○ 목적 : "던지기" 라는 버튼을 누르면, 주사위의 눈이 바뀌고 And "처음부터" 버튼을 누를시, 주사위 눈이 1로 원위치 되도록 하기

과정 :

- 순서1_ 종합적으로 구상된 App 컴포넌트에 React 컴포넌트에서 useState를 import에서 불러오기

=> " import {useState} from 'react' "

- 순서2_ App 컴포넌트 function 내에서 , "어떤 props객체의 속성값을 수정할지" And "setNum메소드"를 변수에 선언 , + useState(수정할 변수의 초기값) 초기화

=> "const [num , setNum] = useState(1); "

- 순서3_ onClick 용 핸들러 작성 :

  • "던지기" : 주사위 눈의 수를 1~6의 난수로 수정 메소드
const handleRollClick = () => {
	const randNum = Math.floor(Math.random()*(6-0) + 1);
    
    setNum(randNum);
}
  • "처음부터" : 주사위 눈의 수를 1로 초기화 메소드
const setReset = () => {
	setNum(1);
}

 

- 순서4_ Button 태그에 onClick 속성 적용 And 동시에 Button 컴포넌트 js파일에서 속성 수정할 생각을 해야함

function App()
{
	//useState() 메소드 사용 세팅 코드
    const [num, setNum] = useState(1);
    
    //onClick용 메소드 2개 => 주사위 돌리기 , 초기화
    //주사위 돌리기 메소드
    const handleRollClick = () => {
    	const randNum = Math.floor(Math.random()*(6-0)) + 1;
    	setNum(randNum);
    }
    //초기화 메소드
    const setRollReset = () =>{
		setNum(1);
	}
    

	return (
    	<>
        	<div>
            	<Button onClick = {handleRollClick}>던지기</Button>//주사위 돌리기 메소드 적용
              	<Button onClick = {setRollReset}>처음부터</Button>//초기화 메소드 적용
            </div>
            <Dice color = "blue" num = {num} />
        </>
    )

}

- 순서5_ Button 컴포넌트 수정 //onClick 적용하기

function Button(
  {children, onClick}
)
{
  return <button onClick={onClick}>{children}</button>
}

export default Button;

 

◎ 연습문제 :

이번 실습에서는 패 고르기 기능을 만들어 봅시다.

버튼을 눌러 가위바위보 패를 내고, 랜덤한 상대방 패를 만들어 결과를 출력해 볼 건데요.

아래를 참고해서 App.js 파일에 state를 사용하는 코드를 작성해 주세요.

state 추가하기

  • ○ hand, otherHand 변수를 state 로 바꾸어 주세요.
  • hand, otherHand state의 초깃값은 'rock' 으로 합니다.

state 값 변경하기

  • ● handleButtonClick 함수
    •   hand state 의 값을 nextHand 로 변경
    •   otherHand state 의 값을 generateRandomHand() 의 리턴 값으로 변경
  •   handleClearClick 함수
    •   hand state 와 otherHand state 의 값을 'rock' 으로 변경

※ 풀이과정 :

● 순서 ①. 코드 구조 파악 :

○ App.js :

import Button from './Button';
import HandButton from './HandButton';
import HandIcon from './HandIcon';
import { compareHand, generateRandomHand } from './utils';

function getResult(me, other) {
  const comparison = compareHand(me, other);
  if (comparison > 0) return '승리';
  if (comparison < 0) return '패배';
  return '무승부';
}

function App() {
  // hand와 otherHand를 state로 바꿔 주세요
  const hand = 'rock';
  const otherHand = 'scissor';

  const handleButtonClick = (nextHand) => {
    // hand의 값을 nextHand 로 바꿔 주세요
    // otherHand의 값을 generateRandomHand()의 리턴 값으로 바꿔주세요
  };

  const handleClearClick = () => {
    // hand와 otherHand의 값을 'rock' 으로 바꿔주세요
  };

  return (
    <div>
      <Button onClick={handleClearClick}>처음부터</Button>
      <p>{getResult(hand, otherHand)}</p>
      <div>
        <HandIcon value={hand} />
        VS
        <HandIcon value={otherHand} />
      </div>
      <div>
        <HandButton value="rock" onClick={handleButtonClick} />
        <HandButton value="scissor" onClick={handleButtonClick} />
        <HandButton value="paper" onClick={handleButtonClick} />
      </div>
    </div>
  );
}

export default App;

○ App.js  내 function 분석

● 순서 ②. useState를 react 컴포넌트 불러오기 => hand, otherHand변수를 useState 초기화

- useState를 react 컴포넌트 불러오기 :

import {useState} from 'react';

- hand 변수 <= useState('rock') , otherHand 변수 <=useState('rock') 적용

function App(){
	
    //hand <= useState 초기화
    const [hand, setHand] = useState('rock');
    
    //otherHand <= useState 초기화
    const [otherHand , setOtherHand] = useState('rock');
    
    //onClick 메소드 코드 작성
    //메소드1
    //내 패 <= 버튼 누른 값 동시에, 상대 패 <= 랜덤하게 패 (utils.js에서 generateRandomHand() 사용)
    const handleButtonClick = (nextHand) => {
		//naxtHand : 버튼에 해당하는 패 인자 전달 매개변수
        
        //hand = nextHand(X)
        setHand(nextHand);
        
        //상대패 랜덤 패로 적용
        setOtherHand(generateRandomHand());
    }
    
    //메소드2 : 내패 , 상대패 모두 'rock'으로 초기화 버튼
    const handleClearClick = () =>{
		setHand('rock');
    	setOtherHand('rock');
	}

}

● 순서 ③. <HandButton> 컴포넌트에 onClick 적용

function App() {
  // hand와 otherHand를 state로 바꿔 주세요
  
  const [hand,setHand] = useState('rock');
  
  const [otherHand,setOtherHand] = useState('rock');
  
  const handleButtonClick = (nextHand) => {
    // hand의 값을 nextHand 로 바꿔 주세요
    setHand(nextHand);//내 패는 버튼을 누른 값으로 전달
    
    // otherHand의 값을 generateRandomHand()의 리턴 값으로 바꿔주세요
    setOtherHand(generateRandomHand());
    
  };

  const handleClearClick = () => {
    // hand와 otherHand의 값을 'rock' 으로 바꿔주세요
    setHand('rock');
    setOtherHand('rock');
  };

  return (
    <div>
      <Button onClick={handleClearClick}>처음부터</Button>
      <p>{getResult(hand, otherHand)}</p>
      <div>
        <HandIcon value={hand} />
        VS
        <HandIcon value={otherHand} />
      </div>
      <div>
        <HandButton value="rock" onClick={handleButtonClick} />
        <HandButton value="scissor" onClick={handleButtonClick} />
        <HandButton value="paper" onClick={handleButtonClick} />
      </div>
    </div>
  );
}