● Defalut 상황
● 1단계 : Defalut의 App.js 컴포넌트를 Board컴포넌트로 수정한뒤, Board컴포넌트 2개(나, 상대)가 들어있는 App.js 적용 후, index.js에 <App> 컴포넌트만 사용해서 작동시켜보기
§ 해당 요구사항 출력 결과 :
§ 과정 :
● 2단계 : "던지기" 버튼 , "처음부터" 버튼 하나로, 2개의 주사위를 동시에 적용되도록 하기
§ 과정 :
○ 순서1_ App 컴포넌트에 useState 메소드를 가져와야 => Board.Blue 컴포넌트, Board.Red 컴포넌트를 동시에 다룰 버튼 적용 가능
function App() {
//나의 패 데이터
const [myNum,setMyNum] = useState(1);
const [mySum,setMySum] = useState(0);
const [myRecord,setMyRecord] = useState([]);
//상대 패 데이터
const [otherNum,setOtherNum] = useState(1);
const [otherSum,setOtherSum] = useState(0);
const [otherRecord,setOtherRecord] = useState([]);
//onClick 메소드 : 던지기
const handleRollClick = () =>{
let randMyNum = Math.floor(Math.random()*(6-0)) +1;
let randOtherNum = Math.floor(Math.random()*(6-0)) +1;
//나의 패 적용
setMyNum(randMyNum);
setMySum(mySum + randMyNum);
setMyRecord([...myRecord, randMyNum]);
//상대편 패 적용
setOtherNum(randOtherNum);
setOtherSum(otherSum + randOtherNum);
setOtherRecord([...otherRecord, randOtherNum]);
}
const setClear = ()=>{
//나의 패 적용
setMyNum(1);
setMySum(0);
setMyRecord([]);
//상대편 패 적용
setOtherNum(1);
setOtherSum(0);
setOtherRecord([]);
}
return (
<>
<div>
<Button >던지기</Button>
<Button >처음부터</Button>
</div>
<Board name="나" color="blue"/>
<Board name="상대" color="red"/>
</>
)
}
○ 순서2_App.js 내부 <Button> 컴포넌트에 [순서1]에서 선언한 useState와 onClick 메소드 적용하기
return (
<>
<div>
<Button onClick={handleRollClick}>던지기</Button>//onClick의 주사위 눈 돌리는 메소드 적용\
<Button onClick={setClear}>처음부터</Button>//onClikck의 Reset하는 메소드 적용
</div>
<Board name="나" color="blue"/>
<Board name="상대" color="red"/>
</>
)
○ 순서3_App.js 내부 [순서1]에서 적용한 나의 주사위 눈 , 점수, 기록 && 상대의 주사위 눈, 점수 , 기록 <Board> 컴포넌트에 적용하기
①. ★<Button> 컴포넌트의 function의 props 객체의 프로퍼티 매개인자 추가 해서, 전달
- Board.js
import Dice from './Dice';
function Board({name , color, num, sum, Record}) {
return (
//.Array프로퍼티 메소드 join(', ')메소드를 이용하여, 배열에 원소 출력
<>
<h1>{name}</h1>
<Dice color={color} num={num} />
<p>총점 : {sum}</p>
<p>기록 : {Record.join(', ')}</p>
</>
)
}
export default Board;
②. 다시, App.js에서 myNum, mySum,myRecord && otherNum, otherSum, otherRecord
- App.js의 function 일부
return (
<>
<div>
<Button onClick={handleRollClick}>던지기</Button>
<Button onClick={setClear}>처음부터</Button>
</div>
<Board name="나" color="blue" num={myNum} sum={mySum} Record={myRecord} />
<Board name="상대" color="red" num={otherNum} sum={otherSum} Record={otherRecord} />
</>
)
§ 최종 코드 결과
◆ App.js :
import { useState } from "react";
import Button from "./Button";
import Board from "./Board";
function App() {
//나의 패 데이터
const [myNum, setMyNum] = useState(1);
const [mySum, setMySum] = useState(0);
const [myRecord, setMyRecord] = useState([]);
//상대 패 데이터
const [otherNum, setOtherNum] = useState(1);
const [otherSum, setOtherSum] = useState(0);
const [otherRecord, setOtherRecord] = useState([]);
//onClick 메소드 : 던지기
const handleRollClick = () => {
let randMyNum = Math.floor(Math.random() * (6 - 0)) + 1;
let randOtherNum = Math.floor(Math.random() * (6 - 0)) + 1;
//나의 패 적용
setMyNum(randMyNum);
setMySum(mySum + randMyNum);
setMyRecord([...myRecord, randMyNum]);
//상대편 패 적용
setOtherNum(randOtherNum);
setOtherSum(otherSum + randOtherNum);
setOtherRecord([...otherRecord, randOtherNum]);
}
const setClear = () => {
//나의 패 적용
setMyNum(1);
setMySum(0);
setMyRecord([]);
//상대편 패 적용
setOtherNum(1);
setOtherSum(0);
setOtherRecord([]);
}
return (
<>
<div>
<Button onClick={handleRollClick}>던지기</Button>
<Button onClick={setClear}>처음부터</Button>
</div>
<Board name="나" color="blue" num={myNum} sum={mySum} Record={myRecord} />
<Board name="상대" color="red" num={otherNum} sum={otherSum} Record={otherRecord} />
</>
)
}
export default App;
◆ Board.js :
import Dice from './Dice';
function Board({name , color, num, sum, Record}) {
return (
//.Array프로퍼티 메소드 join(', ')메소드를 이용하여, 배열에 원소 출력
<>
<h1>{name}</h1>
<Dice color={color} num={num} />
<p>총점 : {sum}</p>
<p>기록 : {Record.join(', ')}</p>
</>
)
}
export default Board;
◆ Button.js :
function Button(
{children, onClick}
)
{
return <button onClick={onClick}>{children}</button>
}
export default Button;
§ 해당 요구사항 출력 결과 :
※ 참고_저렇게 State메소드들을 App에 전부 처리하는 것을 StateLifting이라 한다네요 // 협업에서 쓰이는 용어랍디다.
● React 프로젝트의 보편적인 구조 :
○ App.js :
- state 구현
- 전체적인 틀 (html 부분)
○ Button , Dice : 사진, state에서 주고받는 props.속성을 작성
● 전체적인 코드 정리하기 :
○ 목표 : 굳이 num sum 없이, record배열만으로 작성 정리 해보기
○ App.js 코드 :
import { useState } from "react";
import Button from "./Button";
import Board from "./Board";
function App() {
//나의 패 데이터
const [myRecord, setMyRecord] = useState([]);
//상대 패 데이터
const [otherRecord, setOtherRecord] = useState([]);
//onClick 메소드 : 던지기
const handleRollClick = () => {
let randMyNum = Math.floor(Math.random() * (6 - 0)) + 1;
let randOtherNum = Math.floor(Math.random() * (6 - 0)) + 1;
//나의 패 적용
setMyRecord([...myRecord, randMyNum]);
//상대편 패 적용
setOtherRecord([...otherRecord, randOtherNum]);
}
const setClear = () => {
//나의 패 적용
setMyRecord([]);
//상대편 패 적용
setOtherRecord([]);
}
return (
<>
<div>
<Button onClick={handleRollClick}>던지기</Button>
<Button onClick={setClear}>처음부터</Button>
</div>
<Board name="나" color="blue" Record={myRecord} />
<Board name="상대" color="red" Record={otherRecord} />
</>
)
}
export default App;
○ Board.js 코드 :
import Dice from './Dice';
function Board({name , color, Record}) {
const num = Record[Record.length-1]||1;
let sum =Record.reduce((a,b)=>a+b,0);
return (
//.Array프로퍼티 메소드 join(', ')메소드를 이용하여, 배열에 원소 출력
<>
<h1>{name}</h1>
<Dice color={color} num={num} />
<p>총점 : {sum}</p>
<p>기록 : {Record.join(', ')}</p>
</>
)
}
export default Board;
`
※ Board.js에서 num, sum 계산 부분 설명 :
1. const num = Record[Record.length - 1] || 1;
코드 분석
- Record[Record.length - 1]:
- 배열 Record의 마지막 요소를 가져옵니다.
- Record.length - 1은 배열의 마지막 인덱스를 나타냅니다. 예를 들어:
const Record = [3, 5, 6]; const lastElement = Record[Record.length - 1]; // 6
- 만약 배열이 비어 있다면(Record.length === 0), Record[Record.length - 1]는 undefined를 반환합니다.
- || 1:
- **OR 연산자 (||)**는 단락 평가(short-circuit evaluation)를 사용합니다.
- Record[Record.length - 1]가 Falsy 값(undefined, null, 0, false, NaN, '')일 경우, **대체 값인 1**을 사용합니다.
- 예를 들어:
const Record = []; const num = Record[Record.length - 1] || 1; // undefined || 1 -> num은 1
결론
num 변수에는 Record 배열의 마지막 요소가 저장됩니다. 배열이 비어 있다면 기본값 1이 저장됩니다.
2. let sum = Record.reduce((a, b) => a + b, 0);
코드 분석
- Record.reduce(callback, initialValue):
- reduce 메서드는 배열의 요소를 누적하여 단일 값으로 줄입니다.
- 첫 번째 인수로 전달되는 callback 함수가 배열의 각 요소에 대해 실행됩니다.
- 두 번째 인수인 **initialValue**는 누적값의 초기값으로 사용됩니다.
콜백 함수 (a, b) => a + b
- a는 누적값(accumulator), b는 **현재 요소(current element)**를 나타냅니다.
- 각 요소를 누적값에 더하여 총합을 계산합니다.
initialValue
- 초기값으로 0이 설정되어 있습니다. reduce가 시작될 때 누적값(a)은 0부터 시작합니다.
예제
const Record = [3, 5, 6];
let sum = Record.reduce((a, b) => a + b, 0); // 초기값 0
// 연산 과정:
// 첫 번째 요소: 0 + 3 = 3
// 두 번째 요소: 3 + 5 = 8
// 세 번째 요소: 8 + 6 = 14
console.log(sum); // 14
이 코드가 하는 일
- const num = Record[Record.length - 1] || 1;:
- 배열 Record의 마지막 숫자를 가져옵니다. 배열이 비어 있다면 1을 사용합니다.
- let sum = Record.reduce((a, b) => a + b, 0);:
- Record 배열의 모든 요소를 합산하여 sum 변수에 저장합니다.
관련 코드 동작 예제
// 예제 1: 배열에 값이 있을 때
let Record = [2, 4, 6];
let num = Record[Record.length - 1] || 1; // 마지막 요소인 6
let sum = Record.reduce((a, b) => a + b, 0); // 총합: 2 + 4 + 6 = 12
console.log(`마지막 값: ${num}, 총합: ${sum}`); // 마지막 값: 6, 총합: 12
// 예제 2: 배열이 비어 있을 때
Record = [];
num = Record[Record.length - 1] || 1; // undefined || 1 -> num은 1
sum = Record.reduce((a, b) => a + b, 0); // 초기값 0 (요소가 없으므로)
console.log(`마지막 값: ${num}, 총합: ${sum}`); // 마지막 값: 1, 총합: 0
추가 참고
- **OR 연산자 (||)**는 Falsy 값 처리에 유용합니다.
- Falsy 값: undefined, null, 0, false, NaN, ''.
- Truthy 값은 그대로 사용됩니다.
- reduce 초기값은 필수적:
- 배열이 비어 있으면 초기값이 없을 경우 TypeError가 발생할 수 있습니다.
'CodeIt_Sprint > React_초급' 카테고리의 다른 글
(13)React_초급_React_Design_2_외부CSS파일 불러오기 (0) | 2024.11.25 |
---|---|
(12)React_초급_React가 랜더링하는 방식, React_Design_1_인라인스타일 (0) | 2024.11.23 |
(10)React_초급_ useState() 실습문제 (0) | 2024.11.23 |
(9)React_초급_JSX 문법6 : useState(기본자료형) vs useState(참조자료형) (0) | 2024.11.23 |
(9)React_초급_JSX 문법6 : props객체의 Children 프로퍼티, useState 사용하기 (0) | 2024.11.23 |