useEffect는 단 한번 실행.
강의 코드 타이핑함. 내 레파지토리임
https://github.com/heedaelee/nomadLecture
2021ver 6강 까지 강의 타이핑 중단.
React Api 문서로 이동
const element = <h1>{title}</h1>
React DOM은 기본적으로 렌더링 되기 전에 JSX 내에 포함된 모든 값을 이스케이프 한다 (이스케이프 : html 태그로 해석 하지 못하게 걍 문자로 표현하게 하는것, html태그 탈출한다고 생각하면 편함) 이스케이프 되니깐 XSS(cross-site-scripting) 공격을 막을 수가 있다.
자바 같은 언어를 써봤다면 들어봤을 만한 constructor(생성자)이다. 이것은 자바와 마찬가지로 컴포넌트를 만들 때 처음으로 실행된다. 이 메서드에서는 초기 state를 정할 수 있다.
클래스 컴포넌트에서 반드시 구현돼야하는 유일한 메서드
👀 shouldComponentUpdate가 false이면 실행되지 않는다! 컴포넌트의 props나 state를 활용하여 아래 것 중 하나를 반환하는 역할컴포넌트를 만들고 첫 렌더링을 마친 후 실행
이것은 리렌더링을 완료한 후 실행한다. 업데이트가 끝난 직후이므로, DOM관련 처리를 해도 무방하다.
이것은 리렌더링을 완료한 후 실행한다. 업데이트가 끝난 직후이므로, DOM관련 처리를 해도 무방하다.
(= hook의 useEffect(()=> {return 여기 부분})
과 같다고 보면 된다. useEffect 함수의 return 부분이 언마운트 되기 전에 보통 sideEffect을 제거한다? 거나 input 값 초기화 하는 작업을 하는데 같은 기능이다)
키는 React가 어떤 아이템이 바뀌었는지, 추가됬는지, 삭제됬는지 인식하는데 도움을 줌.
대부분의 경우 데이터의 ID를 키로 함.
여러개의 input 요소를 제어해야할 때 각 요소에 name 속성을 추가한 후 event.target.name 값을 기반으로 핸들러 함수를 고를 수 있습니다.
import React, { Component } from "react";
export default class Reservation extends Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGusets: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
//요거 유용하게 쓰임
//이런식으로 [name]에 사용하는게 좀 낯설고 첨본 사람도 있을텐데
//이렇게 사용하면 어떤 점이 좋냐면
//지금 구조상 const name 이 "isGoing" 일수도
//"numberOfGuests"일수도 있다. 그래서 name = 'isGoing' 이라면
// isGoing: value로 취급되어 위에 생성자내에 this.state의
//isGoing값이 바뀔꺼고
// name='numberOfGuests'이라면 numberOfGuests:value 취급되어
//생성자 내에 this.state의 numberOfGuests 값이 바뀔것이다.
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
checked={this.state.numberOfGusets}
onChange={this.handleInputChange}
/>
</label>
</form>
);
}
}
주어진 input 이름에 해당하는 state 키를 업데이트하기 위해 ES6 computed property name 구문을 사용하고 있습니다.
this.setState({
[name]: value
});
Facebook과 Instagram도 React를 사용했다.. React가 향후 5년동안 프론트를 지배할것이다!!!아마 그럴것이다!!
테이블을 만들때 어떻게 해야 React 스럽게 생각하는 걸까?
컴포넌트는 단일 책임 원칙 (single reponsiblity principle)을 지켜야 한다.
1가지 job만 하는것.
대강 페이지를 그림 그려서 조각 내라 이말임.
이 그림을 보면 알수 있는데, 보통 가장 큰 컴포넌트 흔히 container 라 하는게 기본으로 들어가고, 그담 보면 search 부분이 있는데 파란색 사각형 부분은 다른부분과 공통됨이 없이 유니크하므로 1개 컴포넌트로 보고, 아래것도 크게 1개로 봐서 상,하 이렇게 쪼갤수 있다. 그럼 하위 부분은 한 단계 더 깊게 갈수 있는데, 여기선 취양이 좌지우지 할텐데 Name Price 라벨은 걍 큰 컨테이너에 붙였고, title 1개 컴포넌트 본문 row 1개 컴포넌트로 나눴다.
이게 완전 잘게 쪼갠거고 크게 퍼포먼스 부하 있을거 없고 재생산 할 것도 별로 없으면
title과 본문을 묶어 1개 컴포넌트로 봐도 무방하다.
import React 해와서 만들어란 뜻임. state 등 데이터 고려 없이 걍 UI만
최소한의 state만 사용해라! 쓸데없는 state 만들지 말라 이말임
핵심 : DRY(Don't Repeat Yourself!)
즉 음식점에 어떤 기능의 컴포넌트를 만들때
state들을 state1 = 떡볶이, state2 = 파스타, 된장찌개.. 이러지 말고
let foodState = [떡볶이, 파스타, ..]이런식으로 변수 -> 배열 그렇게 써라는 뜻
대개는 차상위 컴포넌트에 state가 있으면 된다 몇년 전에 velopert 개발자가 설명해서 유명해진 프레젠테이셔널 컴포넌트와 컨테이너 컴포넌트로 나누고, 데이터 state 부분은 컨테이너 컴포넌트의 차상위 부분인 page 기능하는 js 파일에 두고 Top-Down 형식으로 사용했는데,
최근 프로젝트에서 내가 맘에 들어 사용하고 있는 구조는 Component 폴더랑 Page폴더랑 나눠서
page 폴더를 과거 컴포넌트 컨테이너 처럼 redux를 사용하거나 데이터를 받아서 하위 컴포넌트(Component폴더 내에 아토믹으로 설계된 view 기능만 하는 컴포넌트들)에 뿌려주는 구조를 즐겨 쓰고 있다.
이부분은 이해가 조금 안되는데, 역방향이면 보통은 handler 함수 만들어서 최상위 컴포넌트에서 props로 전달해서 하위 컴포넌트에서 그 함수를 받아서 거기에 setState(data) 이런식으로 data를 set 해주면 전체 상위에서 부터 새로운 데이터를 받고 업데이트된다. 즉 컴포넌트가 Container => LoginPage => Form => Input 으로 위계가 잡힌다 쳤을때, Input에서 타이핑 한 text data를 LoginPage에서 사용하고 싶으면 container에서 함수를 만들어서 input까지 Top-Down으로 함수를 내려주고, input 컴포넌트에서 그 함수를 onChange로 건다.
그러면 타이핑 한 데이터는 역방향, 즉 Container 컴포넌트의 우리가 건 함수로 넘어가고, 거기서 setState(데이터) 해주면 위에 전체 컴포넌트가 다 리랜더링 되면서, 데이터를 Container => LoginPage... 등 전달 가능해진다.
그래서 역방향 전송이 가능해진다.
사실 내가 생각하는데 React 사고방식은 UI그릴때 컴포넌트화 시킬수 있는거 그게 전부가 아닐까 생각한다.
출처 : https://reactjs-kr.firebaseapp.com/docs/thinking-in-react.html
담주에 Advance 읽어 봐야겠다
let str = [128, 460, 603, 40, 521, 137, 123];
console.log(solution(str));
// 다른 풀이
function solution(arr) {
let answer,
max = Number.MIN_SAFE_INTEGER;
for (let x of arr) {
let sum = 0,
tmp = x;
//while(true) 일때 계속 무한루프, false면 빠져 나감
while (tmp) {
//1의 자리 추출, 더하기
sum += tmp % 10;
//그후 루프 다시 탐
//1의 자리 제거하고 10,100의 자리를 1의자리 10의자리로 만들어 버리기
tmp = Math.floor(tmp / 10);
}
if (sum > max) {
max = sum;
answer = x;
} else if (sum === max) {
if (x > answer) answer = x;
}
}
return answer;
}
난 숫자를 문자열 전환, for문 돌려서 숫자 낱개로 하나하나 더해서 비교하고 산출했는데
위 알고리즘은 3자리수에 첨에 10을 나눠주고, 나머지는 더해주고, 나눠준 값을
다시 10으로 나누어 자릿수 변경하고 floor 처리 해서 1의자리 제거 해주고 해서..
while() 값이 0까지 루프 돌게 한다음 더해주는 로직이다.
while(조건참이면 돈다){}
while문도 제법 유용한데 오랫동안 안쓰니 낯설게 느껴진다.
function solution(numOfCard, numOfPick, card) {
let answer = 0;
let answerArray = [];
//정렬 부터 해야
card.sort((a, b) => b - a);
for (let i = 0; i < numOfCard; i++) {
for (let j = i + 1; j < numOfCard; j++) {
for (let k = j + 1; k < numOfCard; k++) {
answerArray.push(card[i] + card[j] + card[k]);
}
}
}
// console.log(answerArray);
answer = answerArray[numOfPick];
return answer;
}
let numOfCard = 10,
numOfPick = 2;
let card = [13, 15, 34, 23, 45, 65, 33, 11, 26, 42];
console.log(solution(numOfCard, numOfPick, card));
뽑을 수 있는 모든 3개로 만든 수의 각각 합을 구한다. (같은 수 여러개 있을 수 있음)
그중 k번째 큰 수 출력.
3수를 선택하는데, 제일 큰수, 그다음 큰수, 그다음 큰수 픽 1, 그리고 다음은 ... 마지막에 그다음 큰수 옆의수를
픽 1 .. 다음은 옆의옆의 수를 픽1.. 하는 구조니
즉 세 수를 픽할때 마지막 픽한수가 1회전 돌면, 이제 두번째 픽한수가 한칸 옆으로 가고 또 1회전 돌고..
그럼 2번째 픽하는 수도 1회전 돌면서 윗 과정을 반복하고..
또 2번째 가 1회전 돌면 첫번째 픽한 수도 변경되면서 1회전 도니까
결국 세가지수가 각각의 for문으로 인덱스를 픽해줘야한다. 각각 다들 연달아 1회전씩 돌아야 하니까.
그래서 삼중 for문 만들고 그 합한 값은 1차원 배열에 넣어준 다음!
정해진 k번째 인덱스를 출력해주면 답이 나온다.
출력 : 143 (3번째 큰수가 143)