본문 바로가기

CodeSoom- React 13기

[코드숨] 리액트 13기 -1강/과제 1 - let을 제거해보자 과제 풀이

변수를 선언후 변수의 값을 직접 재할당하지 않고 값을 바뀌게 함

(let을 사용하지 않는 과제 이유 : 직접값을 변경하면 추후 작업에 용이하지 않고, 오류가 날 수 있기 때문 )

let count =0;
const count =0;
 

외부 변수를 let 대신 const로 변경하였을때 에러가 뜬다. (Assignment to constant...)

 

해결방법: 변수로 count를 받는 것

우선 맨 위 코드와 같이 const count=0; 선언한 것을 제외시켜줌(파라미터에 값을 넣어줄것임)

render의 매개변수로 count를 넣어줌

 

마지막 render()에 0을 넣어 초기값을 설정해줌.

 

그리고 아래처럼 각 매개변수로 count를 넣어 실행되도록 함

 

▼ 위 코드에서 아래처럼 더 간략하게 표현 가능

 

▼ 매개변수는 위처럼 해도 작동되지만 대부분 여러개 쓰이는 경우가 많아 { }에 넣어줌.

 

위코드처럼 {}해서 여러개 쓸 경우 맨 아래 render호출하는 부분에 다음과 같이 객체로 아래로 표현

 

클릭함수에도 render 매개변수 객체로 변경

 


 

▼ 내코드 수정전

 
/* @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 count = {
  number: 0,
}; //=>let대신 const를 사용하였으며, 값을 재할당할 수 없으므로 객체를 이용하여
값이 변경되도록 하였다. 이럴시 아래와 같이 .number로 타서 들어가고, 
{Object.values}를 통해 나타나게 하는 등의 번거로움이 있음
/ 왜 let을 사용하지 않을지 생각해보기=>직접 값을 변경할시 추후 오류가 
생기거나 재사용성이 떨어지기 때문. 따라서 파라미터에 값을 전달하는 방법이 유용

function render() {
  function handleClick() {
    count.number += 1;
    render(count);
  }

  function handleClickNumber(value) {
    count.number = value;
    render(count);
  }

  const element = (
    <div id="hello" className="greeting">
      <p>CoseSoom assignment 1</p>
      <p>
        <button type="button" onClick={() => handleClick(count)}>
          Click me!
          (
          {
            Object.values(count)
          }
          )
        </button>
      </p>
      <p>
        {[1, 2, 3].map((i) => (
          <button type="button" onClick={() => handleClickNumber(i)}>
            {i}
          </button>
        ))}
      </p>
    </div>
  );

  document.getElementById('app').textContent = '';
  document.getElementById('app').appendChild(element);
}

render();

 

▼ 내코드 리뷰받고 수정후

/* 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]) => {
    element[key.toLowerCase()] = value;
  });

  children.flat().forEach((child) => {
    if (child instanceof Node) {
      element.appendChild(child);
      return;
    }
    element.appendChild(document.createTextNode(child));
  });

  return element;
}

//
function render(count = 0) {
  function handleClick(number) {
    render(number + 1);
  }

  function handleClickNumber(number) {
    render(number);
  }

  const element = (
    <div id="hello" className="greeting">
      <p>CoseSoom assignment 1</p>
      <p>
        <button type="button" onClick={() => handleClick(count)}>
          Click me!
          (
          {count}
          )
        </button>
      </p>
      <p>
        {[1, 2, 3].map((i) => (
          <button type="button" onClick={() => handleClickNumber(i)}>
            {i}
          </button>
        ))}
      </p>
    </div>
  );

  document.getElementById('app').textContent = '';
  document.getElementById('app').appendChild(element);
}

render();

▼ 아샬 코드

/* @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 count = 0;
}; 외부 변수없어도 됨(매개변수로 넣어줌)
*/

// count를 render함수의 매개변수로 넣음
// function render(count) {..  =>도 가능하지만 여러개 쓰이는 경우가 많아 아래와 같이 *{}사용
function render({ count }) {
  function handleClick() {
    // render(count + 1);
    render({ count: count + 1 }); //*위에 render매개변수 {}써서 * 들도 객체로 써줌
  }

  function handleClickNumber(value) {
    // render(value);
    render({ count: value }); //*
  }

  const element = (
    <div id="hello" className="greeting">
      <p>CoseSoom assignment 1</p>
      <p>
        <button type="button" onClick={() => handleClick(count)}>
          Click me!
          (
          {
            count
          }
          )
        </button>
      </p>
      <p>
        {[1, 2, 3].map((i) => (
          <button type="button" onClick={() => handleClickNumber(i)}>
            {i}
          </button>
        ))}
      </p>
    </div>
  );

  document.getElementById('app').textContent = '';
  document.getElementById('app').appendChild(element);
}

// render(0); // count=0으로 초기설정
render({
  count: 0,
}); //*
 


요구사항

  • ESLint를 돌린 결과 아무런 문제가 없어야 합니다.
  • 모든 인수 테스트를 통과시켜야 합니다.

구현할 기능들

  • 강의를 듣고 index.js를 완성합니다.
  • let을 사용하지 않고 기존과 동일한 동작이 가능해야 합니다. 즉 변수에 값을 재할당 하지 않고 문제를 해결해야 합니다.

// ... let count = 0; function handleClick() { count = count + 1; render(); } // ...


정정

eslint를 실행하면 createElement함수가 선언되었지만 사용하지 않았다는 에러가 발생합니다. createElement함수는 우리가 직접 사용하는 것이 아니라 jsx를 처리할 때 사용되는 함수라서 eslint rule을 수정하지 않고서는 해결할 수 없는 문제입니다.

그런데 전체적으로 no-unused-vars 룰을 disable 하면 다른 곳에서 생긴 문제를 발견할 수 없으므로 해당 함수만 해당 룰을 사용하지 않도록 다음과 같이 수정하는 게 좋습니다.

// eslint-disable-next-line no-unused-vars function createElement(tagName, props, ...children) { // 생략 }

참고