Coding/Today I Learned (148)

07
16

1. 사건의 발단

  • 코드를 짜기 전에 수도 코드를 쓰게 된다. 이것처럼 모든 일에는 계획이 중요하다. 그래서 노션을 사용해 짜는 습관을 들이려고 한다.

2. 슬레시의 사용

  • 노션에서 슬레쉬는 명령어 키이다.
  • 블로그 글 쓸 때처럼 리스트를 작성하거나, 체크박스를 만들거나, 스타일도 바로 넣을 수 있다.
  • 이미지, 동영상, 깃 헙도 바로 연결할 수 있다.
  • 토글을 활용해서 글을 줄여보자. 매우 깔끔하겠지?
  • 주 용한 내용은 콜 아웃으로 강조한다.

3. 트렐로

  • 프로젝트의 형태로 진행과정을 공유하게 된다.
  • 이걸로 프로젝트 진행상황을 공유하는 기업들이 많다고 한다. 사용하면서 익숙해지면 될 것 같다.

4. 템플릿

  • 디자인적인 요소 모든 것을 저장해 두고 언제든지 꺼내 쓸 수 있다.
  • 템플릿을 이용해 아주 다양한 폼들을 받아와서 아예 기업 홈페이지를 없애고 노션을 사용해 대체하기도 한다. 엡에서 공유를 설정해 놓으면 팀이 아닌 인원도 볼 수 있는 홈페이지가 되기 때문이다. 심지어 구글에 검색도 된다!
  • 템플릿은 자신이 직접 만들어 쓸 수 도 있다.

 

간단하게 노션에 대해 정리해 보았다. 일단 사용하면서 여기저기에 사용해 봐야 익숙해질 것 같다.

 

COMMENT
 
07
13

1. Math.sqrt를 사용하지 않은 수숫점 구하기.

  • 입력받은 수를 제곱근 값을 소숫점 두 자리까지만 리턴한다.
  • 셋째 자리에서 반올림한다.
function computeSquareRoot(num) {
  // 기준을 잡아줄 소숫점 자리들의 가장 작은 수를 배열에 만든다.
  const decimal = [1, 0.1, 0.01, 0.001];
  //기준이 될 result를 1로 둔다.
  let result = 1;
  // 반복문으로 기준이 된 result를 제곱해서 num보다 작은 경우
  for (let i = 0; i < decimal.length; i++) {
    while (result * result < num) {
  //result에 소숫점 자리를 더한다. num가 더해진 기준의 제곱보다 커질때 까지 반복.
      result = result + decimal[i];
    }
  // 만약 result의 제곱이 num와 같을때 바로 리턴.
    if (result * result === num) {
      return result;
  // 아니면 소숫점 빼주고
    } else {
      result = result - decimal[i];
    }
  }
  //소숫점 3번째에서 반올림
  return Number(result.toFixed(2));
}
  • 다른 방법으로는 '바빌로니아 법의 점화식'이 있다고 한다. 나는 이해할 수 없다...

2. 카이사르 암호

  • 문자열과 숫자를 입력받아 입력받은 숫자만큼 평행 이동시킨 문자열을 리턴한다.
  • 공백은 무시한다.

[시도 1]

function decryptCaesarCipher(str, secret) {
  // 일단 스트링을 다 split으로 다 땐다.
  let newStr = str.split('');
  // 때어낸 문자를 아스키코드로 변환하여 넣는다.
  let arr = []
  for(let i = 0; i < newStr.length; i++) {
    arr.push(newStr[i].charCodeAt())
  }
  // 지금 이 배열이 아스키 코드로 바꾼 스트링이 들어있는 배열
  let ascii = arr.map(arr => arr - secret)
  let result = '';
  // 배열들을 돌면서 빈칸을 빈칸을 걸러내고
  for(let i = 0; i < ascii.length; i++) {
    if(ascii[i] === 29) {
      result = result + ' '
    } else {
    //남은건 다시 문자로 바꿔서 반환
      result = result + String.fromCharCode(ascii[i])
    }
  }
  return String(arr);
}
  • 실패
  • 아스키코드의 표에서 보면 secret으로 큰 수를 받을 경우, 소문자를 넘어 대문자까지 넘어간다.
  • 소문자 만을 범위로 secret을 정해주어서 97번부터 122번 사이에서만 secret이 변환되도록 만들어야 한다.

[시도 2]

function decryptCaesarCipher(str, secret) {
  let strArr = [abcdefghijklmnopqrstuvwxyz]
  let newStr = str.split('')
  let indexArr = [];
  for(let i = 0; i < newStr.length; i++) {
    indexArr.push(strArr.indexOf(newStr[i]))
    }
  return indexArr
  }
  • 완전히 틀린 코드이다.
  • 아예 나올 수 있는 알파벳을 모두 넣어서 그 배열 속에서 반복문으로 index를 매칭 시키려고 했지만 실패
  • 다시 아스키코드의 범위를 지정하는 방법으로 돌아가기로 하였다.

[시도 3]

function decryptCaesarCipher(str, secret) {
    let newStr = '';
    // str을 split으로 다 자른다.
    let splitStr = str.split('')
    // 자른 newStr에 for...of로 모든 배열들을 다 찾아서
    for(let i of splitStr) {
      // 만약 빈칸이면
        if(i === ' ') {
          // 빈칸을 넣고
          newStr = newStr + ' '
          } else {
            // 만약 아스키 코드 표에서 소문자가 되는 97을 넘으면 맞으면, secret이동 후에 - 122(최대 숫자) 총 알파벳 갯수가 26개 니까 나머지에 122 더한다.
            // 97보다 작으면, secret이동 후에 - 122 그리고 26 나눠서 나머지에 마찬가지 122 더한다.
            newStr = newStr + String.fromCharCode((i.charCodeAt(0) > 97) 
            	? (i.charCodeAt(0) - secret - 122) % 26 + 122 
                : (i.charCodeAt(0) - secret - 122) % 26 + 122)
            };
    }
    return newStr;
}
  • 문제 해결!
  • 조건을 걸 때, 총 알파벳 개수(26)와 최소 97, 최대 122가 나온다는 것을 바탕으로 범위를 정했다.
  • for... of와 삼항 연산자로 코드를 조금 더 간결하게도 바꿨다.
COMMENT
 
07
12

1. 사건의 발단

  • state값으로 form을 만들어서 입력된 값을 다시 state로 올려 렌더링 하는 작업을 하려고 하였다.
  • 직접 state값을 수정해도 가능은 하지만 이는 지양해야 한다. useState를 이용하는 것이 옳다.
  • 그래서 수정한 뒤 결과를 보니 게속 테스트가 통과되지 않는 것이다!!
  • 정작 틀린 부분은 또 오타 때문이었다고 한다...

2. useState 만들기

  const [msg, setMsg] = useState('');
  const [name, setName] = useState('');
  const [newFrind, setNewFrid] = useState([...FrindList]);
  • 먼저, state를 정해주고 다른 파일의 FrindList를 가져왔다.
  • 위의 msg와 name의 입력은 input의 text이고 그 내용은 생략한다.

3. 받아올 객체 폼 만들기

const frind = {
      id: Math.floor(Math.random() * 100000), //거의 무작위에 가까운 id값을 줬다.
      frindName: name,
      content: msg,
    };
  • FrindList에 있는 id와 frindName, content를 이용해 똑같은 구조의 객체 폼을 만들었고, 입력된 내용을 받아 올 것이다.

4. useState로 state값을 변경해 준다.

const newFrindCopy = newFrind.slice(0);
    newFrindCopy.unshift(frind);
    setNewTweet(newFrindCopy);
  • 계속 이어서, 우리가 직접 props로 받은 값을 바꿔주지 않기 위해 복사본을 slice로 만들고, 그 복사본에 unshift를 해서 state를 변경해 준다!

5. 렌더링 하기

const newFrinds = newFrind.map(newFrind => <Frind frind={newFrind} id={newFrind.id} />
  • map을 사용해서 알맞은 컴포넌트에 우리가 얻어온 newFrind를 집어넣고, 어디든지 {newFrind}로 렌더링 할 수 있다.
이처럼 state값을 어느정도 자유롭게 사용할 수 있다고 생각한다. 복사본을 만들면 되니까 말이다. 물론 구조 분해 할당으로 간단하게 해결할 수 도 있지만 좀 더 직관적으로 이렇게 만들어 보았다. 다른 사람들은 조금 이상한 방법이라고 말하기도 했다. 결국 둘 다 잘 작동하니 상관은 없지만 사람들이 자주 사용하는 방법을 사용하는 것이 좋지 않을까?
COMMENT
 
07
11

1. 사건의 발단

  • useState를 올바르게 사용할 수 있게 되었더니 props로 정보를 더 다양하게 주고받으면 범용성이 많이 올라갈 것이라고 생각했다.
  • 지금도 props를 사용하고 있지만 원리를 정확히 알고 사용하는 것이 좋겠다.

2. 기본적인 사용법

  • 부모 컴포넌트에서 자식 컴포넌트로 데이터를 줄 때 사용한다.
  • <컴포넌트 이름 props의 이름 = "주고싶은 값" />의 형태로 사용할 수 있다.
import React from 'react';

function App() {
	return (
		<div>
			<Greet name="Tony Stark" heroName="Iron Man" />
			<Greet name="Steve Rogers" heroName="Captain America" />
			<Greet name="Bruce Banner" heroName="Hulk" />
        	</div>
)}

export default App;
  • 위의 경우  Greet라는 컴포넌트에 Name, heroName이라는 props로 값들이 들어가 있는 형태이다.
  • 자식 컴포넌트에서는 {props.props이름}의 형태로 사용된다.
function Greet(props) {
	return (
		<h1>Hello {props.name} a.k.a {props.heroName}</h1>
)}

// Hello Tony Stark a.k.a Iron Man
// Hello Steve Rogers a.k.a Captain America
// Hello Bruce Banner a.k.a Hulk
  • 아까 부모 컴포넌트에서 받은 props를 이렇게 사용했다.

3. 비구조화 할당을 이용한 사용법

function Greet({ name, heroName }) {
	return (
		<h1>Hello { name } a.k.a { heroName }</h1>
)}

// Hello Tony Stark a.k.a Iron Man
// Hello Steve Rogers a.k.a Captain America
// Hello Bruce Banner a.k.a Hulk
  • 위와 똑같이 작동하지만 조금 더 짧게 사용할 수 있다.

4. defaultProps

  • 컴포넌트에 따로 props를 안 정해놓고 어디서나 사용할 값을 설정할 수 있는 defaultProps를 설정할 수 있다.
  • 그럼 부모가 되는 App.js파일에는 props로 넘겨주려고 하는 값이 없을 것이다.
function Greet({ name, heroname }) {
	return (
		<h1>Hello {name} a.k.a {heroName}</h1>
)}

Greet.defaultProps = {
	name: 'No Name',
    heroName: 'No Heroname'
}

exprot default Greet;

4. 주의점

  • props는 '읽기 전용'이다. 컴포넌트 자체의 props를 수정할 수 없다. 즉 입력값을 변경해 버리면 안 된다.
COMMENT