const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"),
toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = "toDos";
const toDos=[];
// JSON.stringfy
// JSON = JavaScript Object Notation 의 준말. 자바스크립트 오브젝트 표기법
// ex) Object 를 String으로 혹은 String을 Object로 바꿔주기도 한다.
// localStorage key값으로는 Object가 못들어간다. 오직 String만
// 그래서 String으로 변환해야 정상적으로 key값에 들어가는걸 확인할 수 있다.
function saveTodos() {
localStorage.setItem(TODOS_LS, JSON.stringify(toDos))
}
function paintToDo(text) {
const li= document.createElement("li");
const delBtn = document.createElement("button");
const span = document.createElement("span");
const newId = toDos.length+1
delBtn.innerHTML="X";
span.innerText = text;
li.appendChild(span);
li.appendChild(delBtn);
li.id=newId
toDoList.appendChild(li);
const toDoObj = {
text : text,
id : newId
};
toDos.push(toDoObj);
saveTodos();
}
function handleSubmit(event){
event.preventDefault();
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value="";
}
// forEach는 array를 위한 function이다.
// 이와 같은 예로 String도 function이 있고
// Object도 function이 있다.
function loadToDos(){
const loadedToDos=localStorage.getItem(TODOS_LS)
if(loadedToDos !== null){
const parsedToDos = JSON.parse(loadedToDos);
parsedToDos.forEach(function(toDo) {
paintToDo(toDo.text);
});
}
}
function init() {
loadToDos();
toDoForm.addEventListener("submit",handleSubmit)
}
init();
이번 강의에선 브라우저에 출력해놓은 toDoList를 localStorage
key / vlaue 값에 저장하고 그 저장된 값을 브라우저 새로고침을 해도 똑같이 리스트들이 나오게 하는 기능을 추가했다.
첫 번째로 key / value 값에 저장하기 위해 목록 리스트를 담을 배열 변수를 선언해주고
saveToDos() 함수를 생성하고 정의해준다.
두번째로 저번 강의에 만든 loadToDos 함수를 정의해주는데
localStorage의 값을 가져오는 함수를 작성해주고 value값들은 Object로 바꿔주는 JSON.parse를 사용해서 가져온다.
그리고 배열을 위한 function으로 forEach 함수를 사용해서 리스트들은 하나씩 가져와서 브라우저에 리스트로 생성해주는 paintToDo함수를 사용해준다.
다음 강의에서는 버튼을 누르면 list가 삭제되는 기능을 구현해보겠다.
#3.6 Making a To Do List part Three (12:03)
const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"),
toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = "toDos";
let toDos=[];
function deleteToDo(event){
const btn = event.target;
const li = btn.parentNode;
toDoList.removeChild(li);
const cleanToDos = toDos.filter(function(toDo){
return toDo.id !== parseInt(li.id);
});
toDos=cleanToDos;
saveTodos();
}
// JSON.stringfy
// JSON = JavaScript Object Notation 의 준말. 자바스크립트 오브젝트 표기법
// ex) Object 를 String으로 혹은 String을 Object로 바꿔주기도 한다.
// localStorage key값으로는 Object가 못들어간다. 오직 String만
// 그래서 String으로 변환해야 정상적으로 key값에 들어가는걸 확인할 수 있다.
function saveTodos() {
localStorage.setItem(TODOS_LS, JSON.stringify(toDos))
}
function paintToDo(text) {
const li= document.createElement("li");
const delBtn = document.createElement("button");
const span = document.createElement("span");
const newId = toDos.length+1
delBtn.innerHTML="X";
delBtn.addEventListener("click",deleteToDo);
span.innerText = text;
li.appendChild(span);
li.appendChild(delBtn);
li.id=newId
toDoList.appendChild(li);
const toDoObj = {
text : text,
id : newId
};
toDos.push(toDoObj);
saveTodos();
}
function handleSubmit(event){
event.preventDefault();
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value="";
}
// forEach는 array를 위한 function이다.
// 이와 같은 예로 String도 function이 있고
// Object도 function이 있다.
function loadToDos(){
const loadedToDos=localStorage.getItem(TODOS_LS)
if(loadedToDos !== null){
const parsedToDos = JSON.parse(loadedToDos);
parsedToDos.forEach(function(toDo) {
paintToDo(toDo.text);
});
}
}
function init() {
loadToDos();
toDoForm.addEventListener("submit",handleSubmit)
}
init();
이번 강의에서는 list를 지우는 기능을 추가할 것이다.
첫 번째로 버튼의 addEventListener를 생성한다. click 이벤트 발생 시 deleteToDo함수 호출되게
이후 deleteToDo함수를 정의해보자면
첫번째로 버튼을 클릭했을 때 consold.log를 확인해보면 버튼은 클릭된다는 걸 확인할 수 있는데
어떤 리스트의 버튼이 클릭되는지 확인이 불가하다 .그래서 확인이 가능하게 해주는. target을 이용해서
부모 태그인 <li>의 id를 알아내기 위해 parentNode를 사용해서 추출해낸다.
추출 후 html태그에서의 removeChild를 이용해 지워주면 html상 즉 브라우저상에서는 사라진 list를 확인할 수 있다.
하지만 새로고침하면 사라진 list가 다시 생성이 되는데 이는 지워준 리스트 항목들로 교체를 하지 않았기 때문이다.
교체해주기 위해서는 .filter함수를 사용할 건데 안의 콜백 함수의 조건? 에 부합하는 값들로 새로운 Array를 만들어준다.
그러니까 1,2,3 가지의 리스트가 있고 리스트 1의 버튼을 눌러 삭제를했으면 2,3, 의 리스트가 남아 있을 거고 이건 브라우저에 보이는 2,3 리스트이다. 하지만 localStoarage에서는 안 없어져 1,2,3의 리스트가 존재하고 2,3 이남은 Array와 1,2,3, 이 남은 Array를 비교해서 값이 다른 부분을 버리고 남은 부분으로 새롭게 Array를 만들어주는 것
그렇게 새롭게 만든 Array를 toDos에 넣어주고 saveToDos()를 이용해서 새롭게 초기화해준다.
2021-01-19
#3.7 Image Background (13:47)
배경에 사진 넣기
unsplash.com 에서 괜찮은사진 다운로드 받기
const body =document.querySelector("body");
const IMG_NUMBER = 3;
// function handleImgLoad() {
// console.log("finished loading");
// }
function paintImage(imgNumber){
const image = new Image();
image.src=`./images/${imgNumber+1}.jpg`;
image.classList.add("bgImage");
body.prepend(image)
// API환경에서 이 작업을 한다면 이 이벤트리스터가 필요할 것.
//image.addEventListener("loadend",handleImgLoad)
}
function genRandom(){
const number = Math.floor(Math.random()*IMG_NUMBER);
return number;
}
function init(){
const randomNumber = genRandom();
paintImage(randomNumber);
}
init();
사진을 다운로드후
bg.js 파일을생서후 배경화면에대한 함수정의하기
Math 함수를 이용해서 난수발생시키고 거기에 floor 내림 함수를 적용시켜서 사진수만큼 난수발생시킨 숫자를 담는
randomNumber 변수에 넣어 그변수 값을 인자값으로 받는 paintImage 함수 정의 .
const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"),
toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = "toDos";
const toDos=[];
// JSON.stringfy
// JSON = JavaScript Object Notation 의 준말. 자바스크립트 오브젝트 표기법
// ex) Object 를 String으로 혹은 String을 Object로 바꿔주기도 한다.
// localStorage key값으로는 Object가 못들어간다. 오직 String만
// 그래서 String으로 변환해야 정상적으로 key값에 들어가는걸 확인할 수 있다.
function saveTodos() {
localStorage.setItem(TODOS_LS, JSON.stringify(toDos))
}
function paintToDo(text) {
const li= document.createElement("li");
const delBtn = document.createElement("button");
const span = document.createElement("span");
const newId = toDos.length+1
delBtn.innerHTML="X";
span.innerText = text;
li.appendChild(span);
li.appendChild(delBtn);
li.id=newId
toDoList.appendChild(li);
const toDoObj = {
text : text,
id : newId
};
toDos.push(toDoObj);
saveTodos();
}
function handleSubmit(event){
event.preventDefault();
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value="";
}
// forEach는 array를 위한 function이다.
// 이와 같은 예로 String도 function이 있고
// Object도 function이 있다.
function loadToDos(){
const loadedToDos=localStorage.getItem(TODOS_LS)
if(loadedToDos !== null){
const parsedToDos = JSON.parse(loadedToDos);
parsedToDos.forEach(function(toDo) {
paintToDo(toDo.text);
});
}
}
function init() {
loadToDos();
toDoForm.addEventListener("submit",handleSubmit)
}
init();
이번 강의에선 브라우저에 출력해놓은 toDoList를 localStorage
key / vlaue 값에 저장하고 그 저장된 값을 브라우저 새로고침을 해도 똑같이 리스트들이 나오게 하는 기능을 추가했다.
첫 번째로 key / value 값에 저장하기 위해 목록 리스트를 담을 배열 변수를 선언해주고
saveToDos() 함수를 생성하고 정의해준다.
두번째로 저번 강의에 만든 loadToDos 함수를 정의해주는데
localStorage의 값을 가져오는 함수를 작성해주고 value값들은 Object로 바꿔주는 JSON.parse를 사용해서 가져온다.
그리고 배열을 위한 function으로 forEach 함수를 사용해서 리스트들은 하나씩 가져와서 브라우저에 리스트로 생성해주는 paintToDo함수를 사용해준다.
다음 강의에서는 버튼을 누르면 list가 삭제되는 기능을 구현해보겠다.
#3.6 Making a To Do List part Three (12:03)
const toDoForm = document.querySelector(".js-toDoForm"),
toDoInput = toDoForm.querySelector("input"),
toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = "toDos";
let toDos=[];
function deleteToDo(event){
const btn = event.target;
const li = btn.parentNode;
toDoList.removeChild(li);
const cleanToDos = toDos.filter(function(toDo){
return toDo.id !== parseInt(li.id);
});
toDos=cleanToDos;
saveTodos();
}
// JSON.stringfy
// JSON = JavaScript Object Notation 의 준말. 자바스크립트 오브젝트 표기법
// ex) Object 를 String으로 혹은 String을 Object로 바꿔주기도 한다.
// localStorage key값으로는 Object가 못들어간다. 오직 String만
// 그래서 String으로 변환해야 정상적으로 key값에 들어가는걸 확인할 수 있다.
function saveTodos() {
localStorage.setItem(TODOS_LS, JSON.stringify(toDos))
}
function paintToDo(text) {
const li= document.createElement("li");
const delBtn = document.createElement("button");
const span = document.createElement("span");
const newId = toDos.length+1
delBtn.innerHTML="X";
delBtn.addEventListener("click",deleteToDo);
span.innerText = text;
li.appendChild(span);
li.appendChild(delBtn);
li.id=newId
toDoList.appendChild(li);
const toDoObj = {
text : text,
id : newId
};
toDos.push(toDoObj);
saveTodos();
}
function handleSubmit(event){
event.preventDefault();
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value="";
}
// forEach는 array를 위한 function이다.
// 이와 같은 예로 String도 function이 있고
// Object도 function이 있다.
function loadToDos(){
const loadedToDos=localStorage.getItem(TODOS_LS)
if(loadedToDos !== null){
const parsedToDos = JSON.parse(loadedToDos);
parsedToDos.forEach(function(toDo) {
paintToDo(toDo.text);
});
}
}
function init() {
loadToDos();
toDoForm.addEventListener("submit",handleSubmit)
}
init();
이번 강의에서는 list를 지우는 기능을 추가할 것이다.
첫 번째로 버튼의 addEventListener를 생성한다. click 이벤트 발생 시 deleteToDo함수 호출되게
이후 deleteToDo함수를 정의해보자면
첫번째로 버튼을 클릭했을 때 consold.log를 확인해보면 버튼은 클릭된다는 걸 확인할 수 있는데
어떤 리스트의 버튼이 클릭되는지 확인이 불가하다 .그래서 확인이 가능하게 해주는. target을 이용해서
부모 태그인 <li>의 id를 알아내기 위해 parentNode를 사용해서 추출해낸다.
추출 후 html태그에서의 removeChild를 이용해 지워주면 html상 즉 브라우저상에서는 사라진 list를 확인할 수 있다.
하지만 새로고침하면 사라진 list가 다시 생성이 되는데 이는 지워준 리스트 항목들로 교체를 하지 않았기 때문이다.
교체해주기 위해서는 .filter함수를 사용할 건데 안의 콜백 함수의 조건? 에 부합하는 값들로 새로운 Array를 만들어준다.
그러니까 1,2,3 가지의 리스트가 있고 리스트 1의 버튼을 눌러 삭제를했으면 2,3, 의 리스트가 남아 있을 거고 이건 브라우저에 보이는 2,3 리스트이다. 하지만 localStoarage에서는 안 없어져 1,2,3의 리스트가 존재하고 2,3 이남은 Array와 1,2,3, 이 남은 Array를 비교해서 값이 다른 부분을 버리고 남은 부분으로 새롭게 Array를 만들어주는 것
그렇게 새롭게 만든 Array를 toDos에 넣어주고 saveToDos()를 이용해서 새롭게 초기화해준다.
const age = prompt("How old are you");
if ( age>=18 && age <=21 ) {
console.log("you can drink but yon should not")
}else if ( age<18) {
console.log("you cant")
}
else{
console.log("go ahead")
}
prompt를 이용해서 웹페이지가 시작되었을 때 alert와 같은 경고창을 띄울 수 있는데 이는 아주 오래된 JavaScript라서
잘 안 쓰인다고 한다 그냥 그렇다고 한다.
다시 코드를 넘어와서 prompt로 나이를 받아와 조건문을 이용해서 console로그에 띄운 걸 확인할 수 있다.
그리고 console.log를 사용해서 lswinfo.gender를 조회했다 한번 생각해보자.
console.log와 lswinfo.gender의 비슷한 점을 이렇게 적어놓고 나서 보니. log ,. gender 중간에. 이 있는걸
확인할 수 있는데 lswinfo는 Object이다. 이렇듯 console.log 또한 Object임을 알 수 있다.
console.log 는 자바스크립트 안에 있는 것.
console이라는 Object가 있고 log라는 키가 있다.
그리고 이경우의 log는 function(함수)인 것.
하지만 Object이지.
만약 console 오브젝트를 console.log로 찍어보면 어떻게 나올까
Object인 console은 lswinfo보다 더 큰 오브젝트이다.
여기서 보듯이
브라우저가 가지고 있는 자바스크립트는 object에 넣을 수 있다.
이게 우리가 어떻게 자바스크립트가 생겼는지에 대한 매우 좋은 시각을 가질 수 있을 거라고 생각한다.
이제 하나 궁금한 점이 생길 수 있는데
console.log는 어디에서 온 것일까?
console.log, alert 등 우리가 곧 볼 다른 많은 함수들은
내장 함수(built-in function)이라고 한다.
함수(function)란?
function is function
어떤 것의 기능, 기능적인 거
함수는 어떤 걸 수행하려는 한 부분으로,
내가 원하는 만큼 쓸 수 있다.
여기까지 이것이 함수.
한 코드 조각으로 내가 원하는 만큼 쓸 수 있는 것!
예를 들어 console.log로 hello라고 찍히게 하는 코드 조각을 갖고 싶다고 하자.
그리고 함수를 가지고 있지 않다면 그냥 console.log('hello')라고 쓸 것이다.
4번 한다고 하면 마찬가지로 4번을 반복해서 써야겠지.
하지만 인사말을 바꾸고 hello sunwoo , 같이 사람이 계속 바뀐다면 매번 코드를 수정해야 하는
불편함이 있다. 이는 효과적이지 않고 프로그래머들은 게으르다 필요 없는 코드는 필요하지 않다.
console.log('hello')
console.log('hello, lynn)
console.log('hello, sunwoo)
console.log('hello)
// 매우 귀찮다.
우리가 필요한 건 이름을 받아와서 내가 무슨 이름을 주든 hello 해주는 게 나오는 함수가 필요하다.
자바스크립트에서 어떻게 함수를 만들 수 있을까?
먼저 우리가 해야 할 건 function을 주는 것.
그리고 함수 이름을 주는 것이다.
함수의 이름은 sayHello라고 하자.
function sayHello() {
}
바로 이것이 자바스크립트의 함수 정의하는 문법이다.
그리고 이 함수 안에 하나의 인스트럭션을 넣을 것이다.
넣고 나서 함수를 벗어나서 sayHello();라고 쓰면
sayHello();는 Hello라고 나오는 걸 확인할 수 있다.
function sayHello() {
console.log('hello')
}
sayHello()
이것이 이 수업에서 만든 첫 함수이다.
우리는 이제 sayHello를 이용해서 다른 친구들에게도 인사를 건네려고 한다.
건네기 전에 우리는 console.log를 이용해서 복습을 해보자
우리가 여태껏 console.log를 사용해서 콘솔 창에 출력을 해본 경험을 바탕으로 생각해 봤을 때
console.log("hello") ( ) 안에 있는 내용을 출력한다는 걸 예상할 수 있는데 이걸 보고 생각할 때
함수는 ( ) 안에 있는 내용을 사용한다는 걸 확인할 수 있다 그리고 이와 마찬가지로
sayHello("선우") 이렇게 작성한다면 hello 선우 가 출력되지 않을까라고 생각할 수 있는데
실제로 실행해보면 실행이 잘되지 않는 걸 확인할 수 있다. 왜 그런지 생각해보자
일단 첫 번째로 ( ) 사이에 있는 것을 인자(argument)라고 한다.
인자(argument)는 변수 같은 것이다.
그리고 우리 함수는 인자(argument)를 받아 저장을 한다.
그래서 우리는 함수 sayHello를 준비시켜야 한다.
우리가 주는 인자(argument)를 가지고 갈 수 있도록 말이다.
함수를 준비하는 방법은 ( ) 안에 뭘 써주는 것
함수를 만드는 시점에 ( ) 안에 인자(argument)를 넣는 것이다.
뭐든 우리가 원하는 이름을 넣어도 된다.
function sayHello(potato) {
console.log('Hello', potato)
}
sayHello("sunwoo")
여기에 들어간 이름은 위에서 말했듯 변수 같은 것
그리고 parameter 혹은 argument라 불린다.
설정해준 이름은 함수 안에서 사용하게 될 이름이 된다.
그리고 함수를 쓰고 ( ) 안에 무언가를 찾아서 있다면 자바스크립트는 () 안에 들어간 내용을 사용하게 된다.
작동이 잘되는 걸 확인할 수 있고
자바스크립트에서 하는 것은 sunwoo를 potato에 넣고 potato는 console.log 안에 들어가게 되는 것이다.
이것이 외부에 있는 데이터를 읽는 함수를 만드는 방법이다.
함수에게 외부에 있는 데이터를 주는 방법
console.log 함수는 argument를 무한대로 가질 수 있다.
#2. 1 More Function Fun (10:24)
자바스크립트에서는 "" 도 스트링이고 ' ' 도 스트링이다.
만약 큰따옴표로 시작했으면 큰따옴표로 끝내야 하고 작은따옴표 또한 마찬가지이다.
그리고 위에서의 방식으로는 스트링 안에 변수를 집어넣지 못한다.
변수를 넣으려면 "" + 변수 이런 식으로 작성해야 한다
이 방식이 불편해 자바스크립트는 ` ` 백 틱이라는 걸 사용해서 쓸 수 있다.
` ` 을 사용하면 스트링 안에 변수를 넣을 수 있다. 아래 코드를 봐보자.
function sayHello(name, age) {
console.log(`Hello ${name}, you are ${age} years old`);
}
console.log("sunwoo",99);
위 코드를 보면 스트링 안에 변수를 집어넣을 수 있는 걸 확인할 수 있다.
출력또한 잘된다.
함수에는 return을 줄 수 있는데 return은 쉽게 생각하면 물건을 살 때 돈을 지불하고 잔돈을 받는 그런 느낌이다.
return을 보기 전에 아래 코드를 한번 확인해보자.
function sayHello(name, age) {
console.log(`Hello ${name} you are ${age} years old);
}
const greetSunwoo = sayHello("sunwoo",99);
console.log(greetSunwoo);
상수 const greetSunwoo는 sayHello를 호출한다.
함수 sayHello는 console.log를 사용해 무언가를 출력해낸다.
그러고 나서 console.log에 greetSunwoo를 넣으면 정의되지 않았다 나온다.
여기서 헷갈릴 수 있는데 다시 차근차근 생각해보자.
greetSunwoo는 sayHello의 실행된 결과 값이다.
sayHello에서는 아무것도 반환하지 않았다.
그래서 greetSunwoo는 단지 하나의 console.log를 갖게 된다.
이 말이 맞는지 확인해봐야 할 건 sayHello에 무언가를 반환시켜보는 것이다.
function sayHello(name, age) {
return`Hello ${name} you are ${age} years old`;
}
console.log(greetSunwoo);
강의에서는 Instant Propmt Mode를 시도해본 적이 없거나, 경고를 본 적이 없거나 이 모든 것이 무엇을 의미하는지 모를 경우 3번을 선택하시오 Verbose 이렇게 적혀있는 걸 확인할 수 있다 고로 1번 선택
y
멋진 쉘의 모습이 적용된 걸 확인할 수 있다.
VS code에도 적용이 되었나 확인해보자
확인하면 여전히 powershell로 적용된걸 확인할 수 있는데
바뀐거 확인할 수 있다~~
이후 하나 더 바꾸어줘야 하는데 바로 ls colors이다.
ls colors는 아래 글씨 색 이런 거
색을 바꾸기 위해서는 터미널의 설정 파일을 수정해야 한다
. zshrc 파일을 열어보자.
맨 아랫줄에
LS_COLORS="ow=01;36;40" && export LS_COLORS
를 추가해주자.
만약에 터미널의 테마를 변경하고 싶다면 terminalsplassh.com으로 가면 된다.
+ 추가적으로 다시 powerlevel10 k 환경 설정을 하고 싶다면
p10k config를 터미널에 입력하면 된다.
이제 우리는 이걸 어떻게 사용해야 하는지를 배워야 한다. 우분투, 리눅스에 대해 배워야 하는 게 있고, 프로그램은 어떻게 설치하는지콘솔은 어떻게 작동하는지, 리눅스로부터 윈도 파일에 접근할 수 있는지반대로 윈도에서 리눅스 파일에 접근할 수 있는지 다음 파트에서 배운다고 한다.
import React from "react";
import axios from"axios";
class App extends React.Component {
state={
isLoading: true
};
componentDidMount(){
axios.get("https://yts-proxy.now.sh/list_movies.json")
}
render(){
const { isLoading } = this.state;
return<div>{isLoading ? "Loading..." : "We are ready"}</div> // 자바스크립트의 삼항연산자라고 한다 true일시 Loadingd이 false일때 We are ready가 출력되게 만든다.
}
}
export default App;
넣고나서 웹의 Network 창에 보면 무언가 요청하는것이 많은것을 확인할 수 있다.
그리고 아무것도 안나오는것은 우리가 아무것도 안하기 때문이다
우리가 해야할일은 이제 api에서 오는 data를 잡아와야한다 그래야 state안에 사용할 수 있다.
axios.get은 느리다. 그래서 자바스크립트에게 componentDidMount 함수가 끝날 때 까지 약간 시간이 걸릴 수 있다고 말해야하고 우리는 기다려야한다. 그렇게 하기위해 우리는 componentDidMount앞에 async를 넣어줄 것이다.
그리고 우리는 getMovies function을 만든다. 또한 얼마나 기다려야하는지 알려주어야 하기 때문에
axios.get() 옆에 await이라고 적어주자 . 안적어주면 자바스크립트는 기다려주지 않는다. 그리고 이걸 하기위해서 더많은 코드가 필요한 다른일을 해야한다고 한다 그래서 이경우 우리는 async await을 사용해야 한다고 한다.
#4.1 Fetching Movies from API
음 axios를 이용해서 console창에 무엇이 나오는지 확인하고 state안에 넣을 것을 추려낸다.
import React from "react";
import axios from"axios";
class App extends React.Component {
state={
isLoading: true
};
getMovies = async ()=>{
/*
이방법은 효율적이지 않다고한다
const movies = await axios.get("https://yts-proxy.now.sh/list_movies.json")
console.log(movies.data.data.movies); //데이터를 가져오고나서 무엇을 가져왔나 확인하기 위해 작성
*/
// 단축버전
const {data:{data:{movies}}} = await axios.get("https://yts-proxy.now.sh/list_movies.json")
console.log(movies)
}
componentDidMount(){
this.getMovies();
}
render(){
const { isLoading } = this.state;
return<div>{isLoading ? "Loading..." : "We are ready"}</div> // 자바스크립트의 삼항연산자라고 한다 true일시 Loadingd이 false일때 We are ready가 출력되게 만든다.
}
}
export default App;
이런식으로 작성하게되면
state에 넣어야할 내용들을 추려진것을 확인할 수 있다.
state에 movies 배열을 생성하고 스테이트값을 설정해주는데 여기서 전의 자바스크립트라면 this.setState(movies:movies) 이렇게 작성해서 state의 movies는 axios의 movies라고 만들어줘야하는데 최신es6의 자바스크립트는 그냥 통일해서 movies라 작성해도 된다고 한다. 그리고 웹을 보면 바뀌는 반응이 없을텐데 그래서 우리는 isLoading의 값을 바꿔주어야한다. isLoading을 false로 하고 아래에 render로 가보면 we are ready가 써있는것을 확인할 수 있는데 이는 멋지지 않다 그래서 우리는 movies.js라는 새로운 파일을 만들어보자
import React from "react";
import axios from"axios";
class App extends React.Component {
state={
isLoading: true,
movies: []
};
getMovies = async ()=>{
/*
이방법은 효율적이지 않다고한다
const movies = await axios.get("https://yts-proxy.now.sh/list_movies.json")
console.log(movies.data.data.movies); //데이터를 가져오고나서 무엇을 가져왔나 확인하기 위해 작성
*/
// 단축버전
const {data:{data:{movies}}} = await axios.get("https://yts-proxy.now.sh/list_movies.json");
console.log(movies);
this.setState({movies, isLoading: false})
// state에 movies 배열을 생성하고 스테이트값을 설정해주는데
// 여기서 전의 자바스크립트라면 this.setState(movies:movies) 이렇게 작성해서
// satte의 movies는 axios의 movies라고 만들어줘야하는데
// 최신es6의 자바스크립트는 그냥 통일해서 movies라 작성해도 된다고 한다.
// 그리고 웹을 보면 바뀌는 반응이 없을텐데 그래서 우리는 isLoading의 값을 바꿔주어야한다.
// isLoading을 false로 하고 아래에 render로 가보면 we are ready가 써있는것을 확인할 수 있는데
// 이는 멋지지 않다 그래서 우리는 movies.js라는 새로운 파일을 만들어보자
};
componentDidMount(){
this.getMovies();
}
render(){
const { isLoading } = this.state;
return<div>{isLoading ? "Loading..." : "We are ready"}</div> // 자바스크립트의 삼항연산자라고 한다 true일시 Loadingd이 false일때 We are ready가 출력되게 만든다.
}
}
export default App;
movies.js 파일을 만들고 할일은 movies를 render할 것이다.
작성하기 이전에 가져올 데이터를 찾아보자 아까 적어준 API 주소에 들어가보자
들어가면 이렇게 가져올 항목들이 주루룩 뜨는데 여기서 맘에 드는것을 가져와 Movie.js에 작성해준다.
수업 영상을 보고 영상이 진행되는 순서에 맞춰 바로바로 작성하다 보니 장황하고 말 이상하게 쓸 수도 그리고 뇌피셜로 적는 내용이 있을 수 있고 빠짐없이 적고자 하지만 놓친 부분이 있으니 수업내용이 궁금하면 직접 보는 걸 추천드립니다.
결정적으로 웹 HTML만 조금 배운상태에서 진행한거여서 완벽하지 않습니다
아마 이글을 보는 사람이 없을 거 같기는 한데 노파심에
#3. STATE
#3. 0 Class Components and State
1. 기존 존재하는 component들을 지우고 app component를 function component에서 class component로 변경한다.
2. 이후 app component도 지우고 결과적으로 class app component를 만드는데 React.Component를 상속받는다.
ex)
핸드폰 게임을 개발한다면 samsung을 iphone을 프로그래밍하지 않고 cell phone을 프로그래밍한다.
cell phoene 은 여러 가지 특성이 있다. 예를 들면 screen, charger 등등
iphone과 samsung은 이러한 것을 공유한다.
그래서 camera, screnn, charger를 cell phone class에 넣은 다음에서 확장한 samsung class를 가지게 된다.
위에서의 React.Component를 상속받고 만든 class app component는 기본적으로 react class component에서 가져오고 있다. 그리거 거기서 확장하고 있다. 결과적으로 App component는 react component이다.
3. function component와 class component의 차이
- function component는 return을 통해 반환한다. 하지만 class component는 반환을 하지 않는다. function이 아니기에
- 그리고 class react component에는 render method를 가지고 있다.
현재 react component를 상속한 class App component도 동일하게 react component를 가지고 있다.
render 메서드 안에서 리턴 html 문을 작성하면 출력이 되는 것을 확인할 수 있다.
import React from "react";
import PropTypes from"prop-types";
class App extends React.Component {
render() {
return <h1>im a class component</h1>;
}
}
export default App;
결과적으로
Function component는 function이고 뭔가를 return 한다 그리고 screen에 표시가 되고
class component는 class이다 하지만 react component로부터 확장되거 screen에 표시가 된다.
그리고 화면에 표시하기 위해선 render 메서드 안에 넣어야 하고 react는 자동적으로 모든 class component의 render method를 실행하고자 한다.
react는 자동적으로 나의 class component의 render method를 실행한다 자동으로
그 자바 보면 컴파일하려면 main 메서드부터 읽어오는 그러는 느낌인가
4. state는 object이고 component의 data를 넣을 공간이 있고 이 data는 변한다.
그리고 state를 render 안에 넣으려면 class 이기에 this.로 표현해주어야 한다.
import React from "react";
import PropTypes from"prop-types";
class App extends React.Component {
state = {
count: 0
};
render() {
return <h1>im a class component {this.state.count}</h1>;
}
}
export default App;
결과적으로 우리는 state에 바꾸고 싶은 data를 넣는 것
일단 소스코드부터 보고 작성하겠다.
import React from "react";
import PropTypes from"prop-types";
class App extends React.Component {
state = {
count: 0
};
add = () => {
console.log("add");
};
minus = ()=>{
console.log("minus");
};
render() {
return(
<div>
<h1>this number is:{this.state.count}</h1>
<button onClick={this.add}>Add</button>
<button onClick={this.minus}>Minus</button>
</div>
)
}
}
export default App;
일단 보면 add =() =>{} 안에 적혀 이 쓴 게 두 개가 보인다. 이는 javascript 언어라고 한다.
뭘 의미하는지는 정확히 모르겠지만 console.log("add"); 를 나타내게 해주는 역할을 하는 것 같다.
그리고 아래 render 쪽을 보면 두 개의 버튼이 만들어진 것을 확인할 수 있는데 이는 react에서만 작용한다고 한다. 아무튼
이렇게 버튼 두 개에 onClick을 적어 버튼을 눌렀을 때 this.로 위에 만들어진 add와 minus를 실행하게 하는 것 같은데
여기서 주의할게 thsi.add()로 작성하게 된다면 버튼을 누르기도 전에 생성이 된다고 한다. 클릭될 때 동작하게 하려면 ()를 빼주어야 한다고 한다.
아무튼 이렇게 작성 후 버튼을 여러 번 누르고 콘 살창을 확인해보면 숫자가 올라가 있는 것을 확인할 수 있다.
#3. 1 All you need to know about State
State값을 변경하면 웹에 바뀌지 않는 것을 확인할 수 있다. 이는 왜 그러냐면 state값을 변경하면 다시 render를 실행시켜주어야 하는데 실행이 안되어서 업데이트가 되지 않는다. 그래서 우리는 setState를 사용해야 한다. setState를 사용해 값을 변경하면 react는 바로 state를 refresh 하고 바로 render를 불러온다고 한다.
import React from "react";
import PropTypes from"prop-types";
class App extends React.Component {
state = {
count: 0
};
add = () => {
this.state=2;
};
minus = ()=>{
this.setState({count:-1});
};
render() {
return(
<div>
<h1>this number is:{this.state.count}</h1>
<button onClick={this.add}>Add</button>
<button onClick={this.minus}>Minus</button>
</div>
)
}
}
export default App;
위와 같이 add에서는 this.state=로 설정하고 minus는 setState를 이용해서 설정하고 버튼을 눌렀을 때
add버튼 같은 경우 아무 반응이 없고 minus버튼을 누르면 count가 -1로 변경돼서 바로 바뀌는 것을 볼 수 있다.
이는 html 코드로 본다면 react에서 필요한 부분을 빠르게 추가해서 표시해주는 걸 확인할 수 있는데 이때의 속도는 엄청나게 빠르다고 한다.
setState를 사용하지 않으면 새 state와 함께 render function이 호출되지 않을 것이다.
수업 영상을 보고 영상이 진행되는 순서에 맞춰 바로바로 작성하다 보니 장황하고 말 이상하게 쓸 수도 그리고 뇌피셜로 적는 내용이 있을 수 있고 빠짐없이 적고자 하지만 놓친 부분이 있으니 수업내용이 궁금하면 직접 보는 걸 추천드립니다.
아마 이글을 보는 사람이 없을 거 같기는 한데 노파심에 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ
이 부분을 reactJS에서는 component라고 부른다 component의 역할은 보다시피 html을 반환하는 함수이다.
그리고 밑줄 친 부분은 우리가 component를 사용하고자 할 때의 component의 형태이다.
react는 component를 사용해서 html처럼 작성하려는 경우 <App/> 이형식을 가져야 한다.
그리고 javascript와 HTML사이의 이러한 조합을 jsx라고 부른다.
react에서 자바스크립트와 유일하게 배우는 것..?
이렇듯 위의 사진은 component를 사용하는 방법이다.
우리만의 component를 만드는 것은 간단하다
1.src폴더 안에 Potato.js 파일을 만든다.
만들고 component를 만들 때는 항상 import React from "react"; 를 작성해주어야 한다.
안 해주면 react는 여기에 jsx가 있는 component를 사용하는 것을 이해하지 못한다고 한다.
작성 후 아까 hello를 작성했을 때와 동일하게 작성하면 되는데 함수 안에 내용을 작성을 하면
에디터에서 사용되지 않는 함수라고 나오는데 이를 해결하기 위해
export 해주어야 한다고 한다.
이렇게 만든 component를 사용하려면 일단 첫 번째로 생각해볼게 index.js파일에 가서 <App/>이 사용되었듯
Potato를 Import 해서 <App/> 옆에 작성하여 <App/>과 <Potato/>를 react가 가져가게 할 거라고 생각할 수 있는데
react는 하나의 component만을 rendering 해야 하기 때문에 오류가 나오는 것을 확인할 수 있다고 확인하고 해 보는데 잘되는데.. 버전 업데이트를 통해 지원이 가능한 건지는 모르겠는데 나는
이렇게 작성하고 예시를 보여줬는데 동영상에서는 오류가 나왔다. 그런데 1년 전 자료라 그런지 버전 업데이트를 통해 고쳐진 거일지도 모르겠다.
흠 일단 다음 영상을 계속 보면서 이 부분은 따로 알아봐야겠다.
일단 jsx는 javascript 안의 HTML이라고 한다.
음 이 부분을 어떻게 설명해야 할지 모르겠는데 위와 같이 component를 따로 만들어서 사용하면 파일을 왔다 갔다 해야 하는 복잡함이 생겨서 삭제하고 app component안에서 작업을 하는데
위 사진과 같이 App component 안에서 Potato component를 생성해서 App component 안에 넣어 중복해서 사용할 수 있음을 알 수 있다.
예를 들어 i like pizza, i like kimchi와 같이 i like는 동일하게 사용하고 음식만 다른 음식으로 다르게 사용하고자 할 때 component를 여러 개 만들어서 app component에 넣는 것이 아닌 props를 이용하여 Potato component를 인자(argument)를 받게 만들고 {} 감싸고 Potato 부분도 {}로 감싸면 변경해서 계속 사용할 수 있다.
알아보기 쉽게 편의상 Potato -> Food로 바꾸겠다.
+ Component 이름은 대문자로 시작해야 한다.
#2. 2
위와의 방법은 음식을 추가할 때마다 복사 붙여 넣기를 해야 하기 때문에
웹사이트에 동적 데이터를 추가하는 방법
Map을 사용해서 나오게 할 것이며 Map은 Array를 불러와 내가 원하는 arrray로 만들어 가져와주는 역할을 한다.
첫 번째로 일단 좋아하는 음식을 배열로 하나 만든다.
import React from "react";
function Food ( {name}){
return <h1>i like {name}</h1>;
}
const foodlike = [
{
name :"kimchi"
},
{
name : "chicken"
},
{
name : "pizza"
}
]
function App() {
return (
<div>
{foodlike.map( dish=> <Food name={dish.name} />)}
</div>
)
}
export default App;
위를 보면 일단 foodlike를 배열로 만들고
아래 app component에서 map을 만들고 dish라는 이름으로 부르도록 설정한다. 이건 각각의 item인 kimchi chicken pizza를 나타낸다 그러고 위에서의 Food component에 이름을 넘겨주기 위해 dish.name을 적어준다.
그리고 이제 이 음식 사진을 추가적으로 넣어보자.
일단 소스코드는
import React from "react";
function Food ( {name, picture}){
return (
<div>
<h2>i like {name}</h2>
<img src={picture} />
</div>
);
}
const foodlike = [
{
name :"kimchi",
img : "https://www.koreanbapsang.com/wp-content/uploads/2016/10/DSC_1843-e1477360668451.jpg"
},
{
name : "chicken",
img : "https://www.maangchi.com/wp-content/uploads/2018/02/roasted-chicken-1.jpg"
},
{
name : "pizza",
img : "https://www.hapskorea.com/wp-content/uploads/2019/08/black-angus-lobster-ball-pizza.jpg"
}
]
function App() {
return (
<div>
{foodlike.map( dish=> (<Food name={dish.name} picture={dish.img}/>) )}
</div>
)
위와 같이 foodlike에 이미지를 넣어주고
아래 map에 dish.img를 받는 문구를 적고 위에 food에서 이미지를 받는 프로그래밍을 해준다.
이후 renderFood component를 만들어서 foodlike.map에 음식과 이미지 정보를 받아 food component에 넘겨주어 웹에 출력하도록 만들고 app component에 이 쓴 foodlike.map 코드를 간결하게 만들어본다. 그리고 이후에 foodlike.map에
console.log를 적어 웹에서 어떤 식으로 긁어와서 출력되는지 확인한다.
import React from "react";
import {render} from "@testing-library/react";
function Food ( {name, picture}){
return (
<div>
<h2>i like {name}</h2>
<img src={picture} />
</div>
);
}
const foodlike = [
{
name :"kimchi",
img : "https://www.koreanbapsang.com/wp-content/uploads/2016/10/DSC_1843-e1477360668451.jpg"
},
{
name : "chicken",
img : "https://www.maangchi.com/wp-content/uploads/2018/02/roasted-chicken-1.jpg"
},
{
name : "pizza",
img : "https://www.hapskorea.com/wp-content/uploads/2019/08/black-angus-lobster-ball-pizza.jpg"
}
]
function renderFood (dish) {
return <Food name={dish.name} picture={dish.img}/>
}
function App() {
return (
<div>
{console.log(foodlike.map(renderFood))}
{foodlike.map(renderFood)}
</div>
)
}
export default App;
웹에서는 출력이 잘되지만 console창에서 보면 오류가 나와있는 걸 볼 수 있다.
list 내의 child는 unique 한 key prop을 가져야 한다고 나와있다.
그래서 foodlike component의 배열 값들에 id값을 준다. id 값을 주고 오류에서 나온 key값을 정해준다.
이후 웹페이지에 돌아가서 console창을 확인해보면 오류가 안 나와있는 것을 확인할 수 있다.
import React from "react";
import {render} from "@testing-library/react";
function Food ( {name, picture}){
return (
<div>
<h2>i like {name}</h2>
<img src={picture} />
</div>
);
}
const foodlike = [
{
id:1,
name :"kimchi",
img : "https://www.koreanbapsang.com/wp-content/uploads/2016/10/DSC_1843-e1477360668451.jpg"
},
{
id:2,
name : "chicken",
img : "https://www.maangchi.com/wp-content/uploads/2018/02/roasted-chicken-1.jpg"
},
{
id:3,
name : "pizza",
img : "https://www.hapskorea.com/wp-content/uploads/2019/08/black-angus-lobster-ball-pizza.jpg"
}
]
function renderFood (dish) {
return <Food key={dish.id} name={dish.name} picture={dish.img}/>
}
function App() {
return (
<div>
{console.log(foodlike.map(renderFood))}
{foodlike.map(renderFood)}
</div>
)
}
export default App;
결과적으로 foodlike에 id값을 준 것은 food component에서는 사용하지 않는다 기본적으로 react에서 사용하기 위해 설정해준 것이다. react에서는 모든 element들이 다르게 보일 필요가 있다. id값을 주기 이전의 foodlike의 코드를 보면 우리는 각각의 사진과 이름을 가지고 있다는 것을 알지만 react는 알지 못하기에 우리가 이렇게 id값을 정해주고 key를 넣어주는 것
+ 추가적으로 img 태그에서 alt ={name} 이 부분이 없었는데 이번 영상을 보면서 나는 못 적은 부분이 적혀있길래 내가 놓친 부분이라고 생각했는데 추가적으로 이영상 뒤에 설명이 나왔다 img 태그에는 alt prop 이 반드시 있어야 하고 있어야 하는 이유에는 시각장애인들을 위해 있어야 한다고 한다.
#2. 4 Protection with PropTypes ( props에 원하는 props가 들어가 있는지 점검하기)
- father component로부터 전달받은 props가 우리가 예상한 props 인지
1. foodlike에 있는 각각의 음식에 rating(점수 매겨보기 )
2. 이후 터미널에 npm i prop-types 입력하여 기능(?) 설치
- 이를 설치하여 아까 작성했던 코드에서 picture를 보내야 하는데 image를 보낸다면 component가 잘못될 텐데
cmd창에 documents에 접속 후 npx명령어와 만들 app의 이름을 설정해주고 실행한다.
설치가 완료되면 이렇게 나온다.
6. VSC로 돌아가서..
documents에 생성된 movie_app_lsw을 열면 목록에 여러 가지 나오는데 그중
package.json에 들어가서 start, build만 남기고 나머지는 지워준다 안 쓴다고 한다.
터미널 창에 npm start를 입력해 만든 movie_app_lsw을 시작해보자
시작이 정상적으로 되었다면 이화면을 확인할 수 있다.
7. 만든 것을 깃허브에 넣자
vsc 터미널을 이용해서 깃허브에 넣을 건데
터미널에 입력 시 깃허브의 저장소를 만들어주어야 하는데
이런 식으로 만들고
터미널에 이렇게 넣으면 되는데 커밋을 잘 못써서 두 번 썼는데 위에 한 줄만 저렇게 써주면 된다. 그리고 푸시하고 확인하면 저장소에 들어간 모습을 확인할 수 있다.
8. 만들어진 경로의 폴더를 살펴보면
3가지의 폴더 중 src폴더의 index파일의 3,5번 라인의 글을 지운다. 기본적인 설명을 위해 불필요한 부분을 지운다고 한다.
더불어 14,15,16,17 라인도 지운다.
그리고 소스 폴더에 있는 몇 가지 파일을 지운다.
그리고 App.js에서 import logo 부분을 삭제한다. (로고 파일을 지웠기 때문에)
더불어 div를 비워준다
이렇게 했는데 오류가 나와서 처음부터 다시 하는데 vsc는 익숙지 않아 쓰던 intellij를 이용해 다시 했는데 홈페이지에서 오류가 나오는 것이다. 이미지 파일을 찾을 수 없다나 그래서 잘 보니 리턴 바로 오른쪽에다 div태그가 있어야지 된다. 아무튼 저렇게 작성하면
빈화면이 나온다.
작동 은하지만 아무것도 나타내지 않는 빈공 백의 상태의 페이지를 확인할 수 있다.
그 후 appjs에 div태그를 감싸 hello!! 를 작성하면 hello! 가 출력이 되는 것을 확인할 수 있다.
여기서 웹에서 소스코드를 확인해보면 아래쪽에 div태그 안에 hello 있는 것을 확인할 수 있다.
그런데 에디터에서 public 폴더의 index.html 파일에 들어가면 내가 div태그 안에 작성한 hello는 찾아볼수 없는데 이것이 react가 html을 사용하는 방법이다 react는 처음부터 html을 넣지 않고, html에서 html을 추가하거나 제거하는 방법을 알고있다. 그래서 application에서 이것을 로드할때 빈 html을 로드하게 되고 그런다음에 react가 html을 밀어넣게 된다 방금 작성한 div태그안에 hello를
이를 증명(?) 하는 자료로는 index.js의 파일 안에는 getElementByID가 있는데 public의 index.html에도 getElementByID의 값인 root가 존재하는 걸 확인할 수 있다.
이렇게 빈 html에 react가 html을 추가해서 넣는 게 react의 작동방식이라고 한다.
virtual DOM : virtual document object model
가상의 존재 소스코드에서는 존재하지 않지만 react가 만들어낸다
이렇게 작동하면 엄청 속도가 빠르다고 한다 가상이고 존재하지 않아서...
뇌피셜로는 필요할 때마다 코드(?)들을 넣어줘서 처음부터 코드(?) 전체를 넣고 시작하지 않아도 돼서 빠른 건가