해당 게시글에는 풀이가 있습니다. 풀이를 보기 전에...한번 더 혼자 힘으로 해보시는 것을 추천드립니다!
1주차 과제는 매개변수와 인자를 이용하여 값을 관리하는 과제였다.
해당 과제를 하면서 eslint가 설정이 되어 있었기 때문에 꽤나 까다로웠다.
동작은 하는 듯 했으나, eslint에서 에러가 발생했고, 이를 없애기는 생각보다 쉽지 않았다.
/* eslint-disable react/react-in-jsx-scope, react/jsx-filename-extension */
/* @jsx createElement */
function createElement(tagName, props, ...children) {
const element = document.createElement(tagName);
Object.entries(props || {}).forEach(([key, value]) => {
if (key === 'onClick') {
element[key.toLowerCase()] = value;
return;
}
element[key] = value;
});
children.flat().forEach((child) => {
if (child instanceof Node) {
element.appendChild(child);
return element;
}
element.appendChild(document.createTextNode(child));
return element;
});
return element;
}
function render(count = 0) {
const handleClick = (number) => {
render(number + 1);
};
const handleClickNumber = (value) => {
render(value);
};
const element = (
<div id="hello" className="greeting">
<p>CodeSoom first assignment</p>
<p>{count}</p>
<p>
<button type="button" onClick={() => handleClick(count)}>Click</button>
</p>
<p>
{[1, 2, 3].map((i) => <button type="button" onClick={() => { handleClickNumber(i); }}>{i}</button>)}
</p>
</div>
);
document.querySelector('#app').textContent = '';
document.querySelector('#app').appendChild(element);
}
render();
function
키워드를 이용하면 호이스팅이 되는 것으로 알고 있는데, 계속해서 eslint에서는 'render' was used before it was defined
라는 에러를 주는 게 아닌가? 그래서 궁금했다. 호이스팅이 되더라도 사용하기 전에 선언하는 것이 권장되는 방식인지...
/* 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 or = (num1, num2) => (num1 === null ? num2 : num1);
const operationFunctions = {
'+': (num1, num2) => num1 + num2,
'-': (num1, num2) => num1 - num2,
'*': (num1, num2) => num1 * num2,
'/': (num1, num2) => num1 / num2,
};
const defaultFunctions = (num1, num2) => or(num2, num1);
const initialState = {
accumulator: 0,
number: null,
operator: '',
};
// eslint-disable-next-line max-len
const calculate = (operator, accumulator, number) => (operationFunctions[operator] || defaultFunctions)(accumulator, number);
function render({ accumulator, number, operator }) {
const handleClickNumber = (value) => {
render({ accumulator, operator, number: (number || 0) * 10 + value });
};
const handleClickOperator = (value) => {
render({
accumulator: calculate(operator, accumulator, number),
operator: value,
number: null,
});
};
const handleReset = () => {
render(initialState);
};
const element = (
<div>
<p>간단 계산기</p>
<p>{or(number, accumulator)}</p>
<div>
<div>
{
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((value) => <button type="button" onClick={() => handleClickNumber(value)}>{value}</button>)
}
</div>
<div>
{
['+', '-', '*', '/', '='].map((value) => <button type="button" onClick={() => handleClickOperator(value)}>{value}</button>)
}
</div>
<div>
<button type="button" onClick={handleReset}>reset</button>
</div>
</div>
</div>
);
document.getElementById('app').textContent = '';
document.getElementById('app').appendChild(element);
}
render(initialState);
변수명은 동사보다는 형용사나 수동태를 사용해야 된다
1주차 과제는 매개변수를 이용한 과제이다 보니, 매개변수가 점점 많아졌다.
RORO 패턴은, 객체를 받아서, 객체를 반환한다는 의미를 줄인 것이다.
RORO 패턴을 공부하기 위해서는 비구조화할당(destructurin)을 알아야 된다.
function findUser(id, password, email) {
console.log(id);
}
findUser('sejinee', 123, 'sejinee@aaa.com');
function findUser({id, password, email}) {
console.log(id)
}
findUser({id: 'sejinee', password: 123, email: 'sejinee@aaa.com'})
→ 두 코드를 보았을 때, 매개변수에 객체를 받은 쪽이 더 읽고 이해하기 쉽다
function findUser(id, student= false, password, email, ) {
console.log(student)
}
findUser('sejinee', undefined, 123, 'sejinee@aaa.com')
// 인자에 undefined로 전달하지 않으면, student에 부여했던 default 값이 변함
function findUser({id, student= false, password, email} = {}) {
console.log(student)
}
findUser({id: 'sejinee', password: 123, email: 'sejinee@aaa.com'})
→ 아래와 같이 객체를 전달하면 undefined 값을 쓰지 않고, 디폴트 값을 보존할 수 있다.
(아직 RORO 패턴을 읽어보면서, 이해한 것은 이 두 가지 장점이었다! 해당 게시글에 가면 더 다양한 장점이 있다...)
shadowing은 로컬 변수가 포함된 스코프의 변수와 동일한 이름을 공유하는 프로세스이다. 이런 경우, 코드를 읽을 때도 혼동이 발생할 수 있고, 원하는 값에 접근할 수 없는 일이 발생한다.
간단계산기 과제를 하면서 operator 값을 가져오는데 이러한 문제가 발생했었다. eslint에서 no-shadow
라고 알려줬음에도 알지 못했었다. 그래서 원하는 값을 가져오지 못한 채로 2시간 넘게 끙끙거렸다.
매개변수의 이름을 바꿔주니 금방 해결된 걸 보고, no-shadow의 중요성을 몸소 느꼈다.
1주차 과제를 하면서 받은 피드백들을 정리해봤습니다.
remove let은 매개변수를 이용하라는 힌트를 얻어, 금방 완료했다.
하지만 간단 계산기는 말과는 다르게 간단하지 않았다.
처음에는 직접 구현한 코드를 유지해서 보완해 나가고 싶었다...😭
하지만 계속 0과 먼저 계산이 된 채로 연산이 되어, 더하기는 정상적으로 작동하는 모습을 보였고, 나머지 연산을 해본 결과 제대로 작동이 안되길래, 결국 풀이 영상을 보고 완료했다.
시간이 있을 때, 직접 구현했던 코드를 가지고 간단 계산기 작업을 완료하고 싶다. (마무리 되지 않아서 그런지 머리속에 더 아른아른거림)
❗️틀린 내용이 있거나 문제가 있는 경우 댓글로 말씀해주시면 수정하도록 하겠습니다!!