오류
main.js:287 Uncaught RangeError: Maximum call stack size exceeded
=>계속 실행됨
▼ 오류원인
<button type="button" onClick={handleClickOperator('+')}>
+
</button>
▼ 해결: 함수를 그냥 넣어주게 아니라 () 해서 작성했기 때문에 아래와 같이 작성해야 함.
<button type="button" onClick={() => handleClickOperator('+')}>
+
</button>
▼ 아샬코드
/* @jsx createElement */
function createElement(tagName, props, ...children) {
const element = document.createElement(tagName);
Object.entries(props || {}).forEach(([key, value]) => {
element[key.toLowerCase()] = value;
});
children.flat().forEach((child) => {
if (child instanceof Node) {
element.appendChild(child);
return;
}
element.appendChild(document.createTextNode(child));
});
return element;
}
//
// ㄱ.const defaultFunction = (x, y) => x || y;
/* ㄴ.
function plus(x, y) {
return x + y;
} */
const operatorFunctions = {
/* '': (x, y) => x || y, // 처음엔 x가 없으니까 y만
'=': (x, y) => x || y, // 처음엔 x가 없으니까 y만 */
/* ㄴ. 위의 함수를 끌어쓰고 싶으면
'+': plus, // 이렇게도 표현가능한데 여기선 간략한 거 씀 */
'+': (x, y) => x + y,
'-': (x, y) => x - y,
'*': (x, y) => x * y,
'/': (x, y) => x / y,
};
function or(x, y) {
return x === null ? y : x;
}
// ㄱ다르게 표현
function defaultFunction(x, y) {
return or(y, x);
// return y, x;
}
function calculate(operator, accumulator, number) {
return (operatorFunctions[operator] || defaultFunction)(accumulator, number);
}// ||defaultFunction : 함수값을 못얻으면 이거 출력 ex:만약 ''버튼이 없거나 =가 없는 경우를 설정해서 위처럼 없어도 작동되게 할 수 있다}}
//
const initialState = {
accumulator: 0, // 계속해서 누적돼서 계산되는값,result도 가능 (12누르고 + 9 일경우 129가 안되게 +누른순간 12를 저장해야함=>12가 누적된다)
number: null,
operator: '',
};
function render({ accumulator, number, operator }) {
function handleClickReset() {
render(initialState);
}
function handleClickNumber(value) {
render({
accumulator,
number: (number || 0) * 10 + value,
operator, // operator:operator, 축약
});
}
function handleClickOperator(value) {
render({
accumulator: calculate(operator, accumulator, number), // 기존에 입력했던 숫자값
number: null,
operator: value,
});
}
const element = (
<div>
<p>CoseSoom assignment 2</p>
<p>{or(number, accumulator)}</p>
{/* 없을경우는 다른거 보여줌 */}
<p>
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((i) => (
<button type="button" onClick={() => handleClickNumber(i)}>
{i}
</button>
))}
</p>
<p>
{['+', '-', '*', '/', '='].map((i) => (
<button type="button" onClick={() => handleClickOperator(i)}>
{i}
</button>
))}
<button type="button" onClick={handleClickReset}>
Reset
</button>
</p>
</div>
);
document.getElementById('app').textContent = '';
document.getElementById('app').appendChild(element);
}
render(initialState);
▼ 내코드 중간 (끝인줄 알았으나 오류발견)
/* eslint-disable react/react-in-jsx-scope, react/jsx-filename-extension, no-unused-vars */
/* @jsx createElement */
function createElement(tagName, props, ...children) {
const element = document.createElement(tagName);
Object.entries(props || {}).forEach(([key, value]) => {
element[key.toLowerCase()] = value;
});
children.flat().forEach((child) => {
if (child instanceof Node) {
element.appendChild(child);
return;
}
element.appendChild(document.createTextNode(child));
});
return element;
}
const initialState = {
number: 0,
resultNumber: 0,
operator: '',
};
const operators = {
'': (x, y) => y,
'+': (x, y) => x + y,
'-': (x, y) => x - y,
'*': (x, y) => x * y,
'/': (x, y) => x / y,
'=': (x, y) => y,
};
function calculate(number, resultNumber, operator) {
return operators[operator](resultNumber, number);
}
function render({ number, resultNumber, operator }) {
function clickNumber(value) {
render({
number: number * 10 + value,
resultNumber,
operator,
});
}
function clickOperator(value) {
render({
number: 0,
resultNumber: calculate(number, resultNumber, operator),
operator: value,
});
}
const element = (
<div>
<h3>CoseSoom assignment 2</h3>
<p>간단 계산기</p>
<p>{number || resultNumber}</p>
<p>
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((i) => (
<button type="button" onClick={() => clickNumber(i)}>
{i}
</button>
))}
</p>
<p>
{Object.keys(operators).filter((data) => data !== '').map((i) => (
<button type="button" onClick={() => clickOperator(i)}>
{i}
</button>
))}
</p>
</div>
);
document.getElementById('app').textContent = '';
document.getElementById('app').appendChild(element);
}
render(initialState);
오류
1.강의를 들은후 다시 살펴보니, 위 코드에서 오류발견(5+5=10, 이상태에서 -를 다시 누르고5하면 계산된 값이
나와야하는데 내꺼는 다시 0으로 리셋되게 만들어버림)
2. 9+0을 누르면 0이 위에 누른 숫자출력에 보여야하는데 안보임 =>number값을 null이었을때를 이용하여 수정
(강의 참고)
정정
- defaultFunction에서 x와 y를 다루는 순서가 반대로 되어 있어서 순서를 바꿔야 합니다.
- 0이 입력이 안되는 문제가 있습니다.
JavaScript에서는 null을 이용해서 정말로 빈 값을 표현할 수 있습니다. or라는 함수를 만들어서 0은 그대로 사용하고 null일 때만 다른 값을 취하게 하여 문제를 해결할 수 있습니다.
▼ 강의에 써있는 말 이해돕기(number를 null값으로 수정하여 0을 눌렀을때도 출려되게 만들어줌)
▼이를 통해 수정한 내 최종 코드
/* eslint-disable react/react-in-jsx-scope, react/jsx-filename-extension, no-unused-vars */
/* @jsx createElement */
function createElement(tagName, props, ...children) {
const element = document.createElement(tagName);
Object.entries(props || {}).forEach(([key, value]) => {
element[key.toLowerCase()] = value;
});
children.flat().forEach((child) => {
if (child instanceof Node) {
element.appendChild(child);
return;
}
element.appendChild(document.createTextNode(child));
});
return element;
}
const initialState = {
number: null,
resultNumber: 0,
operator: '',
};
const operators = {
'+': (x, y) => x + y,
'-': (x, y) => x - y,
'*': (x, y) => x * y,
'/': (x, y) => x / y,
'=': (x, y) => x || y,
};
function or(x, y) {
return x === null ? y : x;
}
function defaultFunction(x, y) {
return or(y, x);
}
function calculate(number, resultNumber, operator) {
return (operators[operator] || defaultFunction)(resultNumber, number);
}
function render({ number, resultNumber, operator }) {
function clickNumber(value) {
render({
number: (number || 0) * 10 + value,
resultNumber,
operator,
});
}
function clickOperator(value) {
render({
number: null,
resultNumber: calculate(number, resultNumber, operator),
operator: value,
});
}
function handleClickReset() {
render(initialState);
}
const element = (
<div>
<h3>CoseSoom assignment 2</h3>
<p>간단 계산기</p>
<p>{or(number, resultNumber)}</p>
<p>
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((i) => (
<button type="button" onClick={() => clickNumber(i)}>
{i}
</button>
))}
</p>
<p>
{Object.keys(operators).filter((data) => data !== '').map((i) => (
<button type="button" onClick={() => clickOperator(i)}>
{i}
</button>
))}
<button type="button" onClick={handleClickReset}>
Reset
</button>
</p>
</div>
);
document.getElementById('app').textContent = '';
document.getElementById('app').appendChild(element);
}
render(initialState);
'CodeSoom- React 13기' 카테고리의 다른 글
[코드숨] 리액트 13기 -2강/ 1. React (0) | 2022.10.19 |
---|---|
[코드숨] 줄바꿈을 LF로 처리중인 프로젝트를 Window에서 협업하는 방법 (0) | 2022.10.19 |
[코드숨] 리액트 13기 -1강/과제 1 - let을 제거해보자 과제 풀이 (0) | 2022.10.19 |
[코드숨] 리액트 13기 - git hub 참고(fork, add) (0) | 2022.10.12 |
[코드숨] 리액트 13기 -1강/JSX(Babel) (0) | 2022.10.11 |