[한입 리액트] JS 응용

미아·2022년 12월 29일
0

REACT

목록 보기
4/41

Truthy & Falsy

        /*
        자바스크립트의 특징을 이용한 boolean 값을 넣지 않아도 참이나 거짓으로 나오는 속성이 있다.
        truthy : true 같은 값
                ex. [](빈배열),{}(객체리터럴), 숫자, "0", "false"(문자열), Infinity
        falshy : false 같은 값  
                ex. ""(빈문자), undefined(null과의 차이: 변수에 아무것도 할당하지 않은 값) , null, 0, -0, NaN
        */
        let a = "0";
        if (a) console.log("true");
        else console.log("false");



        /* 이걸 어떻게 활용할까? */
        const getName = (person) => {
            if (!person) { //true가아니면 들어와라!
                return "객체가 아닙니다" // 예외처리 
            }
            return person.name;
        };

        let person = { name: "이경미" }; //person변수에 객체 저장
        let undef; //변수 선언 후 값을 안넣었으니, 당연히 undefined
        const name = getName(person); //함수 호출후, 변수 name에 저장
        const name2 = getName(undef);
        console.log(name); //값이 찍힘
        console.log(name2); //undefined도 에러나지 않게 예외처리 필요!

        // 예외처리 할때 아주 유용!

삼항 연산자

        /* 양수/ 음수 확인 */
        let a = 3;
        let con = (a > 0) ? console.log("양수") : console.log("음수");
        /* 빈 배열인지 확인 */
        let b = [];
        b.length === 0 ? console.log("빈 배열!") : console.log("배열에 값이 있다!");
        //값에 넣어서도 사용가능!

        let c; // undefined , falsy값
        let d = []; // truthy값
        const result = c ? true : false; // false 반환
        const result2 = d ? true : false; // true 반환

        console.log(result);
        console.log(result2);

        /* 성적 표기 프로그램(중첩 삼항 연산자) - 가독성 떨어진다, if가 나음! */
        // 90점 이상이면 A+, 50점 이상이면 B+, 둘다 아니면 F
        let score = 90;
        // const my_score = score >= 90 ? "A+"
        //     : score >= 50 ? "B+" // 첫번째 조건이 아니면 한번 더 비교
        //         : "F"; // 그것도 아니면 한번 더 비교

        /*if 조건문으로 변경*/
        let my_score;
        if (score >= 90) my_score = "A+";
        else if (score >= 50) my_score = "B+";
        else my_score = "F";
        console.log(my_score);


단락 회로 평가

        /* 단락 회로 평가 : 왼쪽에서 오른쪽으로 연산하는 순서를 이용한 문법임!*/

        console.log(false && true); //&&는 둘다 true여야 t이므로, false 보자마자 바로 false 반환
        console.log(true || false); //||는 하나만 true여도 t이므로, true 보자마자 바로 true 반환

        /* 단락 회로 평가 간지나게 이용하기 */
        const getName = (person) => {
            // if (!person) return "객체가 아닙니다";
            // return person.name;
            const name = person && person.name;
            //(객체 있을 경우) name에는 &&연산자로인해, 두 조건다 확인후 person.name값인 dlrudal 반환
            //(객체 없을 경우) &&연산자로 인해, flase이므로, null값 담김
            return name || "객체가 아닙니다.";
            //(객체 있을 경우) ||는 하나만 t여도 반환하므로 dlrudal 반환
            //(객체 없을 경우) ||는 두개다 t여야 반환이므로 뒤 조건까지 확인 후 "객체가 아닙니다" 반환
        };
        // let person = { name: "dlrudal" };
        let person = null;
        const name = getName(person);
        console.log(name);

조건문 업그레이드

    /*여러개의 조건일때 조건에 맞으면 t / 아니면 f를 반환하는 함수*/

    function isKoreanFood(food) {
        if (["불고기", "떡볶이", "비빔밥"].includes(food)) {
            return true;
        }
        return false;
    }
    console.log(isKoreanFood("불고기"));
    console.log(isKoreanFood("파스타"));
    /* 많은 유형을 조건식으로 반환해야 할 때 유용하게 사용 가능 - 객체 이용*/
    const meal = {
        한식: "불고기",
        중식: "멘보샤",
        일식: "초밥",
        양식: "파스타",
        인도식: "카레"
    };
    const getMeal = (mealType) => {
        return meal[mealType] || "굶기";
    }
    // function getMeal(mealType) {
    //     return meal[mealType] || "굶기";
    // }
    console.log(getMeal("중식"));
    console.log(getMeal());

비구조화 할당

        /*
        - 비구조화 할당: 배열이나 객체의 속성 혹은 값을 해체하여 그 값을 변수에 각각
        담아 사용하는 자바스크립트 표현식.
        */
        /* 배열의 비구조화 할당 */
        let arr = ["one", "two", "three"];
        let [one, two, three] = arr;
        // let [one, two, three] = ["one", "two", "three"];
        // let one = arr[0] 이랑 같은 말, 변수에 값 담는 것
        console.log("배열 비구조화 할당")
        console.log(one, two, three)

        /*배열의 비구조화 할당 (기본값)*/
        let [four, five, six, seven = 7] = [4, 5, 6];
        console.log(four, five, six, seven); // seven은 할당 안해주면 undefined
        //sevne = 7 이런식으로 기본값 바로 할당해주는 것 가능

        /* swap !! */
        /*원래 방식*/
        let a = 20;
        let b = 10;
        let tmp = 0;

        tmp = a;
        a = b;
        b = tmp;
        console.log("a,b의 값" + a, b);
        /*배열 비구조화 방식 이용*/
        let c = 20;
        let d = 10;
        [c, d] = [d, c]
        console.log(c, d)

        /* 객체의 비구조화 할당(리액트에서 중요!!!!) */
        console.log("객체의 비구조화 할당");
        let object = { one1: "one", two2: "two", three3: "three" };
        let { one1, two2, three3, four4 = "four" } = object; //기본값 할당 가능
        console.log(one1, two2, three3, four4);
        //배열에서 비구조화 할당을 사용할 경우, 좌항의 각 변수에는 같은 인덱스 가진 우항의 값 할당
        //객체는 키값을 기준으로 할당한다.(우항의 키값이 좌항의 변수명과 매칭), 즉 같은 이름 사용해야!
        // 순서도 상관없다, 키값 기준으로 가져옴! 

        /* + 객체의 키값 대신 변수명 사용하기 */
        let { name: user_name, age: user_age, gender: user_gender }
            = { name: "이경미", age: 26, gender: "여" }
        console.log(user_name, user_age, user_gender);
        // 객체의 프로퍼티 값은 d 이런식의 "" 없는 값을 할당하려고 하면 변수로 인식함.

Spread 연산자

        /* script 연산자 : 중복된 요소들이 많을때 쓰는 방법
            spread: 펼쳐주다!, 즉 객체의 중복되는 요소들을 펼쳐줄때!
            주로 객체, 배열의 복사, 연결의 용도로 활용도가 높다!
        */

        //Object
        const cookie = { base: "cookie", madIn: "Korea" };
        const chocoCookie = { ...cookie, toping: "chocho" };
        const strawberryCookie = { ...cookie, toping: "strawberry" };
        console.log(chocoCookie, strawberryCookie); // cookie가 전부 복사된걸 볼 수 있다!

        //Array
        const arr1 = [1, 2, 3, 4, 5];
        const arr2 = [...arr1, 6, 7, "히히", 8, 9];
        console.log(arr2); // arr1+arr2가 사용된 것을 볼 수 있다.

        //String -> Array
        let string = "abcdefg";
        let arr = [...string];
        console.log(arr);

동기와 비동기


-> 자바스크립트는 싱글 스레드로 동작한다

  • process: 메모리 상에서 실행 중인 작업
    (프로세스는 메모리 안에서 서로 독립적으로 실행되는 작업, 각각의 프로세스는 서로 메모리 공유를 하지 않는다.)

    출처: https://artistjay.tistory.com/6
  • thread : 이러한 프로세스 내의 실행 단위

자바스크립트 싱글스레드 작업 수행 방식

-> 그럼 스레드를 분할해서 넣으면 되겠네!, 하지만 자바스크립트는 싱글 스레드로 동작함!


🙋‍♀️비동기 방식으로 한번에 처리해버리면, 어떤 일이 언제 끝났는지 어떻게 알지?

  • 콜백함수를 사용하면 됨

  • 실습

        /* 동기와 비동기 */

        /* 동기 방식 */
        console.log("**동기 방식**");
        function taskA() {
            console.log("A 작업 끝");
        }
        taskA();
        console.log("코드 끝"); //a 작업이 끝날때까지는 "코드 끝"이라는 코드를 읽을수 없음(동기처리)

        /* 위 코드를 비동기 방식으로 바꿔보기 */
        console.log("**비동기 방식**");
        //setTimeout : 자바스크립트에서 제공하는 비동기 함수
        function taskB() {
            setTimeout(() => { console.log("A Task End") }, 2000);
        } // 2초후 실행
        taskB();
        console.log("코드 끝");

        /* 비동기 처리의 결과값을 콜백함수로 전달해서 이용하기 */
        console.log("**비동기 방식+콜백함수**");

        function taskC(a, b, cb) {
            setTimeout(() => {
                const res = a + b; //우린 a+b 값을 밖에서도 알아보길 원함
                cb(res); // function으로 들어가서 결과값 나옴 cb(7)인거처럼!
            }, 2000);
        }
        taskC(3, 4, (res) => { console.log("2초후에 나오는 결과" + res) }) //나중에 실행
        console.log("코드 끝"); // 먼저 실행되고 

        /* 1초 뒤에 전달받은 파라미터 값 *2 하는 함수 만들기 */
        function double(a, cb) {
            setTimeout(() => {
                const res = a * 2;
                cb(res);
            }, 1000);

        }
        double(3, (res) => {
            console.log("1초 후에 나오는 결과" + res);
        });

->setTimeOut 특성상 console창 보기 어려워서 첨부 안함! 직접 복붙해서 넣어본 뒤 확인해보자~

Js 엔진

  • heap: 변수, 상수들에 사용되는 메모리 저장하는 영역
  • callStack: 작성한 코드의 실행에 따라서 호출 스택을 쌓는 영역

js 엔진 구동하는 방식

-main context : 자바스크립트 최상위 문맥임, 가장 먼저 들어온다. (= 프로그램이 시작되는 시점임, main context가 나간다면 프로그램 종료되는 시점)

call stack의 특징

  • call Stack은 종료되면 바로 빠짐!
  • 가장 마지막에 들어온 애부터 가장 먼저 빠짐(like 프링글스 통)

비동기방식 js엔진에서 구동하는 방식


1) asyncAdd함수 실행되면서 call Stack에 들어오고
2) setTimeout()실행되는데, 바로 callstack에 안들어온다


-> asyndAdd() 먼저 끝나고

-> callback Queue로 옮겨지고
-> callStack으로 옮겨간다!

콜백지옥

        /* 비동기 프로그램 만들기 */
        function taskD(a, b, cb) {
            setTimeout(() => {
                const res = a + b;
                cb(res);
            }, 3000)
        }

        function taskE(a, cb) {
            setTimeout(() => {
                const res = a * 2;
                cb(res)
            }, 1000)
        }

        function taskF(a, cb) {
            setTimeout(() => {
                const res = a * -1;
                cb(res)
            }, 2000)
        }

        taskD(4, 5, (a_res) => {
            console.log("D REULST", a_res);
            taskE(a_res, (b_res) => {
                console.log("E RESULT", b_res);
                taskF(b_res, (c_res) => {
                    console.log("F RESULT", c_res);
                })
            })
        }) //콜백지옥임...
        console.log("코드 끝")

promise

  • 비동기작업은 3가지 상태를 가진다!
        /* 콜백지옥을 해결할 수 있는 비동기처리 객체! */

        // resolve - 성공 , reject - 실패
        function isPositive(number, resolve, reject) {
            //비동기로 해줄거라 setTimeout 걸어줌
            setTimeout(() => {
                if (typeof number === "number") {
                    console.log(number);
                    resolve(number >= 0 ? "양수" : "음수")
                } else {
                    reject("주어진 값이 숫자형 값이 아닙니다.")
                }
            }, 2000)
        }

        // 콜백을 이용한 비동기 처리
        // isPositive(
        //     [],
        //     (res) => {
        //         console.log("성공적으로 수행함:", res);
        //     },
        //     (err) => {
        //         console.log("실패하였음:", err)
        //     }
        // )

        // promise를 이용한 비동기 처리
        function isPositiveP(number) {
            const executor = (resolve, reject) => { //executor 실행자
                setTimeout(() => {
                    if (typeof number === "number") {
                        console.log(number);
                        resolve(number >= 0 ? "양수" : "음수");
                    } else {
                        reject("주어진 값이 숫자형 값이 아닙니다.")
                    }
                }, 2000)
            }

            const asyncTask = new Promise(executor);
            // promise 객체 생성해서, promise의 실행으로 executor 함수를 넘겨주면,
            // 전달하는 순간 자동으로 executor 함수 수행됨
            return asyncTask; // 반환값이 promise 임
        }

        isPositiveP(101);
        /* promise 객체 사용해보기
            1. 변수에 담기
            2. 변수. then(콜백함수).catch(콜백함수)
            (promise객체의 메서드인 then 과 catch 사용한것!)
        */
        const res = isPositiveP([]);
        res.then((res) => { console.log("작업성공:", res) }).catch((err) => { console.log("작업실패:", err) })
        //resolve 실행시 -> then에서 받아오고 ,
        //reject 실행시 -> catch에서 받아온다.
  • 비동기예제로 다뤘던 콜백지옥 가독성있게 promise로 바꿔보기!
        /*
        비구조화할당에서 했던 예제를 => promise로 간단하게 바꾸기

        promise를 반환하는 함수로 바꾼 이유 :
        그 함수가 비동기적으로 동작하고, 반환한 promise 객체 이용해서 비동기처리의 결과값을 then, catch로 이용할수 있다!
        */
        function taskA(a, b) { // 콜백함수 지우면 됨
            return new Promise((resolve, reject) => {
                // executor 변수 만들어서, promise 객체에 넣어준거랑 같음!
                setTimeout(() => {
                    const res = a + b;
                    resolve(res); // then에서 받을 수 있음
                }, 3000)
            })
        }
        function taskB(a) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    const res = a * 2;
                    resolve(res);
                }, 1000)
            })
        }
        function taskC(a) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    const res = a * -1;
                    resolve(res);
                }, 2000)
            })
        }

        //-> 이런식으로 쓰면 콜백함수 쓰는것과 다를 바 없다.
        // taskA(5, 1).then((a_res) => { //then은 reslove 됐을때
        //     console.log("A RESULT:", a_res);
        //     taskB(a_res).then((b_res) => {
        //         console.log("B RESULT:", b_res);
        //         taskC(b_res).then((c_res) => {
        //             console.log("C RESULT:", c_res);
        //         })
        //     })
        // })

        //then 쓰는 방식 , (then 체이닝 방식)
        const bPromiseResult = taskA(5, 1)
            .then((a_res) => {
                console.log("a result:", a_res);
                return taskB(a_res); // promise 객체인 a_res값이 담겨서 return됨 taskB 호출
            })
        // 호출부와
        console.log("중간에 이런것도 넣을 수 있답니다")
        bPromiseResult  //결과부 나눠서 쓸수도 있고, 중간에 추가도 가능하다!
            .then((b_res) => {
                console.log("b result:", b_res);
                return taskC(b_res);
            })
            .then((c_res) => {
                console.log("c result:", c_res);
            })


        // typeA(3, 4, (a_res) => {
        //     console.log("TYPE A:", a_res);
        //     typeB(a_res, (b_res) => {
        //         console.log("TYPE B:", b_res);
        //         typeC(b_res, (c_res) => {
        //             console.log("TYPE C:", c_res)
        //         })
        //     })
        // })

이해하며 정리하는 부분!

  • 동기: 이전 작업의 실행이 끝나야 다음 작업 실행을 시작한다.
  • 비동기: 이전 작업의 실행과 무관하게 다음 작업을 시작한다.

->js 는 기본적으로 동기식이지만, api 요청보낼때 응답이 올 때 까지 마냥 기다릴수 만은 없기 때문에 비동기 처리가 필요하다! (동기처리방식으로만 사용한다면 모든 순서가 다 끝날때까지 기다려야한다!)

✏️ 하지만 비동기처리방식을 사용한다면, 의도하지 않은 순서로 함수가 실행될 수 있기때문에 원하는 부분에서 동기방식으로 변환해줘야함!!

해결방법 1️⃣: 콜백함수
-콜백함수 : 함수 안에서 또 다른 함수를 호출하는 것!
(but, 여러 함수를 순서대로 호출할 필요가 있을 경우, 콜백 지옥을 경험 !)

해결방법 2️⃣: promise객체

  • promise는 성공(resolve 함수 호출), 실패(reject 함수 호출)

보통의 식
const promise = new Promise((resolve, reject) => {구현식});

        // promise를 이용한 1초 뒤 성공하는 상황 구현!
        function success() {
            //function으로 사용한다면 return 해줘야 함수 밖에서도 값 알아볼 수 있으므로
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    //성공하려면 뭐가 필요해? resolve
                    resolve("성공");
                }, 1000)
            })
        }
        // 성공시 then메소드(콜백) 해서 구현해준다!
        success().then((n) => console.log(n)); // then함수 활용해서 resolve 호출해서 console로 찍음

        //promise를 이용해 1초 뒤 실패하는 상황 구현
        function fail() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject(new Error()) // "실패"라고 해줘도 상관없다.
                }, 1000)
            })
        }
        fail().catch((n) => { console.log(n) })


-> 요런 형태가 callback hell!

async / await - 직관적인 비 동기 처리 코드 작성하기

        /* async / await - 직관적인 비 동기 처리 코드 작성하기*/

        // async 

        function hello() {
            return 'hello';
        }

        //async 키워드 붙여주면 자동으로 promise 리턴하는 비동기 처리 함수가 된다!
        async function helloAsync() { //helloAsync에 마우스 커서 올려보면 => promise 반환하는 것 알수 있음!
            return 'hello Async';
        }

        console.log(hello(), helloAsync());
        // promise 객체로 return 한다는 소리는 => then 쓸수 있다는 소리!
        helloAsync().then((res) => {
            console.log(res) // res 어디서 옴? async 키워드 붙이면 resolve(res)와 같은 효과를 냄!(return)
        })

        /* await */
        //전달받은 파라미터만큼 delay 되는 함수 만들거다!
        function delay(ms) {
            // return new Promise((resolve)=>{
            //     setTimeout(()=>{
            //         resolve();  setTimeout 함수 안에 resolve 호출말고 없으면, 그냥 resolve 만 써줘도 된다.
            //     },ms)
            // })
            return new Promise((resolve) => {
                setTimeout(resolve, ms);
            })
        }

        async function newAsync() {
            // return delay(3000).then(() => { return "hello newAsync" })
            await delay(3000); // await키워드가 붙은 함수의 호출은 함수가 끝나기 전까지
            // 아래있는 코드 수행 안함(동기처리 한다는 뜻)
            //await은 async 키워드가 있어야만 사용가능!
            return "hello newAsync"
        }

        //main에서 hello newAsync 출력해보자!
        async function main() {
            const res = await newAsync();
            console.log(res);
        }
        main();
        newAsync().then((res) => {
            console.log(res);
        })

API & FETCH

  • api란?
  • client : 요청함
  • response: 응답함
    🙋‍♀️즉 api호출 : 다른 프로그램한테 데이터를 받기 위해, 말을 건다!
    (응답 실패하기도 하기때문에, promise 객체에 reject가 있는것임!)

json placeholder


-> dummy data 쓸수있는 사이트

        //fetch 함수: 자바스크립트에서 api 호출 돕는 내장함수
        let response = fetch('https://jsonplaceholder.typicode.com/posts')
            .then((res) => console.log(res)) //promise 반환하는 함수
        // 결과값은 객체로 나옴.(선물의 포장지같은 개념, 포장지 안을 뜯어서 확인해야함!)

        // dummy data는 json형태로 되어있음
        async function getData() {
            let rawResponse = await fetch("https://jsonplaceholder.typicode.com/posts");
            let jsonResponse = await rawResponse.json();
            console.log(jsonResponse);
        }
        getData();
profile
새로운 것은 언제나 재밌어 🎶

0개의 댓글