newChobo
article thumbnail

개발 시작할 때

npm start 명령어를 통해 개발자서버를 열 수 있다

6.0 Introduction

import Button from "./button"
import styles from "./App.module.css";
import { useState } from "react";

function App() {
  const [counter, setValue] = useState(0);
  const onClick = () => setValue((prev) => prev + 1); //이전 값을 활용해 다음 값을 만들어내도록 인자를 주었음

  return (
    <div>
      <h1>{counter}</h1>
      <button onClick={onClick}>click me!</button>
    </div>
  );
}

export default App;

 

아래(수강일지 02)에서는 current를 변수로 활용하였는데, 그냥 아무 단어나 써도 상관이 없는건가???????

            const onInvert = () => {
                setInverted((current)=>!current);
                reset();
            }

변수명을 바꿔보아도 정상작동 하였음.

기존에 있던 변수와 이름이 겹쳐도 알아서 내부에서 굴림.

식을 받아왔음을 스스로 잘 인지하는듯

 

 

원인은 모르겠으나, 콘솔에 render가 2번씩 출력됨

-----------

2분 17초쯤에 console창에 render가 두번씩 뜨는 현상이 있는데,
index.js에서 React.StrictMode 태그를 삭제 하시면 됩니다.
StrickMode는 create-react-app으로 설치를 하시면 기본적으로 생성이 되어있는 태그인데
해당 태그로 감싸져 있는 경우에는 코드의 문제를 감지하고 경고하기 위해서
구성 요소를 두 번 렌더링 한다고 합니다.(개발용이 아닌 프로덕션용)

------------

강의에서 한분이 작성해두신 답변이 있었음. 그대로 따라가니 해결됨

 

 

import { useState } from "react";

function App() {
  const [counter, setValue] = useState(0);
  const onClick = () => setValue((prev) => prev + 1); //이전 값을 활용해 다음 값을 만들어내도록 인자를 주었음
  console.log('render');

  return (
    <div>
      <h1>{counter}</h1>
      <button onClick={onClick}>click me!!</button>
    </div>
  );
}

export default App;

 

state가 변해도 랜더를 여러번 하지 않도록 한다?

어떻게 특정 코드들이 첫번째 component render에서만 실행되게 하는가?

현재 우리가 값이 변경된 것을 볼 수 있는 이유는 우리 state가 변경될때 모든 코드가 동작하기 때문이다.

여러번 반복되면 낭비인 코드가 있을텐데, 그런것들을 처음 한번만 실행되도록 하려면?

 

        4.1 Memo : https://newchobo.tistory.com/38

 

노마드코딩 수강일지 03

#4 PROPS 4.0 PROPS 저번 시간에 배운것 const [amount, setAmount] = React.useState(0); const onChange = (event) => { setAmount(event.target.value); } {index === "xx" ? "Please select your units": null} 오늘 Props : 부모컴포넌트로부터 자

newchobo.tistory.com

//버튼을 여러번 눌러도 state는 한번만 바뀌어서 여러번 동작하지는 않는군.
내부 value값이 그대로라 변할 필요가 없는 Continue도 render되는것을 알 수 있다.
이는 낭비로 보임.
그래서 React Memo가 필요함.
라고 했었는데, 한번 짚어보고 올 필요가 있을듯

 

 

강의에서 한 댓글

memo는 state가 변경되는 경우에만 렌더링이 되는 것 같고, useeffect는 아예 state가 변경되어도 렌더링이 안되는 것 같아요. 그래서 api 같은 1번만 불러와도 되는 경우에 쓰이는 것 같고

 

 

6.1 useEffect

React팀에서 만들어둔 useEffect 라고 하는 function이 있다.

2개의 인자(argument)를 받아온다.

첫번째 인자는 우리가 한번만 실행하고 싶은 코드가 된다.

두번째 인자는 마법같은 친구, 나중에 설명.

 

import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function App() {
  const [counter, setValue] = useState(0);
  const onClick = () => setValue((prev) => prev + 1); //이전 값을 활용해 다음 값을 만들어내도록 인자를 주었음
  console.log('I run all the time');
  const iRunOnlyOnce = () =>{
    console.log('I run only once.');
  };
  useEffect(iRunOnlyOnce, []);    //2번째인자의 비어있는 배열은 당장은 생각하지 말자

  return (
    <div>
      <h1>{counter}</h1>
      <button onClick={onClick}>click me!!</button>
    </div>
  );
}

export default App;

 

// 익명함수 사용

import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function App() {
  const [counter, setValue] = useState(0);
  const onClick = () => setValue((prev) => prev + 1); //이전 값을 활용해 다음 값을 만들어내도록 인자를 주었음
  console.log('I run all the time');
 
  useEffect(() => {
    console.log('CALL THE API...');     //익명함수 사용
  }, []);    //2번째인자의 비어있는 배열은 당장은 생각하지 말자

  return (
    <div>
      <h1>{counter}</h1>
      <button onClick={onClick}>click me!!</button>
    </div>
  );
}

export default App;
 
 
useEffect function은 우리 코드가 한번만 실행될 수 있도록 보호해준다.

 

6.2 Deps 

이전 영상에서 배웠던 그 2번째 인자가 무엇인지 알 수 있을듯 하다

 

React Memo vs useEffect

React Memo vs useEffect

아래 코드의 경우, 검색창의 문자가 바뀌었을때를 위한 동작이 버튼을 클릭했을때도 동작함.

 
import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function App() {
  const [counter, setValue] = useState(0);
  const [keyword, setKeyword] = useState("");

  const onClick = () => setValue((prev) => prev + 1); //이전 값을 활용해 다음 값을 만들어내도록 인자를 주었음
  const onChange = (event) => setKeyword(event.target.value);
 
  console.log('I run all the time');
  useEffect(() => {
    console.log('CALL THE API...');     //익명함수 사용
  }, []);    //2번째인자의 비어있는 배열은 당장은 생각하지 말자
  console.log("SEARCH FOR", keyword);

  return (
    <div>
      <input
        value={keyword}
        onChange={onChange}
        type="text"
        placeholder="Search here..."
      />
      <h1>{counter}</h1>
      <button onClick={onClick}>click me!!</button>
    </div>
  );
}

export default App;

 

원하는 때에만 코드가 실행하도록 바꿔준 코드

import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function App() {
  const [counter, setValue] = useState(0);
  const [keyword, setKeyword] = useState("");

  const onClick = () => setValue((prev) => prev + 1); //이전 값을 활용해 다음 값을 만들어내도록 인자를 주었음
  const onChange = (event) => setKeyword(event.target.value);
 
  console.log('I run all the time');

  useEffect(() => {
    console.log('I run only once.');     //익명함수 사용
  }, []);             //2번째 배열이 비어있으므로, 한번만 동작함. 변화할 값이 없음
  useEffect(() =>  {
    //★하지만, useEffect 코드는 처음 실행할때 자동으로 실행되고 검색 되고 시작함
    //그래서 조건문을 통해 조건을 만족할때만 동작하게 설정할 수도 있음
    if(keyword !== "" && keyword.length > 5){
      console.log("I run when 'keyword' changes.");
    }    
  }, [keyword]);      //2번째 배열에 들어있는 변수 값이 변화하면 다시 동작함. 리엑트가 2번째 인자 안의 값들을 지켜본다
 
  useEffect(() =>  {
    console.log("I run when 'counter' changes.");
  }, [counter]);

  useEffect(() =>  {
    console.log("I run when 'counter' or 'keyword' changes.");
  }, [counter, keyword]);   // 배열 안의 값 중 하나가 바뀌면 동작

  return (
    <div>
      <input
        value={keyword}
        onChange={onChange}
        type="text"
        placeholder="Search here..."
      />
      <h1>{counter}</h1>
      <button onClick={onClick}>click me!!</button>
    </div>
  );
}

export default App;

 

6..3 Recap

Dependencies는 React가 지켜봐야 하는 것들이다?

첫번째 argument는 우리가 실행시키고 싶어하는 코드

두번째 argument는 dependencies라고 하며, react가 지켜보면서 변화하면 해당 코드들 동작시킨다.

 

2번째 인자가 비어있는 배열이면 단 한번만 실행하게 될 것.

 

6.4 Cleanup

Cleanup function?

자주 쓰이는 기능은 아니지만, 알아둬서 나쁠것 없겠지.

 

import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function Hello(){
  useEffect(()=> {
    // show 할때마다 동작하게 되는데, 이는 hide할때 컴포넌트가 지워졌다가 새로 생성된 것이기 때문이다.
    // 컴포넌트가 새로 생성된 것이기 때문에, 코드도 반복하는것처럼 보일 뿐 다른 놈이 실행하는것
    console.log("I'm here!");      
  }, []);
  return <h1>Hello</h1>
}

function App() {
  const [showing, setShowing] = useState(false);
  const onClick = () => {
    setShowing(prev => !prev)
  }
  return (
    <div>
      {/* 자바스크립트 쓸 때는 괄호 쳐야함 */}
      {showing ? <Hello /> : null}
      <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
    </div>
  );
}

export default App;
 
 
컴포넌트가 사라질 때에도 함수를 동작시킬 수 있다?
import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function Hello(){  
  useEffect(()=> {
    // show 할때마다 동작하게 되는데, 이는 hide할때 컴포넌트가 지워졌다가 새로 생성된 것이기 때문이다.
    // 컴포넌트가 새로 생성된 것이기 때문에, 코드도 반복하는것처럼 보일 뿐 다른 놈이 실행하는것
    console.log("created :)");      

    // 컴포넌트가 사라질 때 동작하는 코드
    // Cleanup function
    return () => console.log("destroyed :(");
  }, []);
  return <h1>Hello</h1>
}

function App() {
  const [showing, setShowing] = useState(false);
  const onClick = () => {
    setShowing(prev => !prev)
  }
  return (
    <div>
      {/* 자바스크립트 쓸 때는 중괄호 쳐야함 */}
      {showing ? <Hello /> : null}
      <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
    </div>
  );
}

export default App;
 
 

당연하지만, 함수를 리턴하는것도 가능하다.

아래와 같이 변경도 할 수 있음

import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function Hello(){  
  function byFn(){
    console.log("bye :(")
  }

  function hiFn() {
    console.log("created :)");
    return byFn;    // Cleanup function 실행
  }

  useEffect(hiFn, []);
  return <h1>Hello</h1>
}

function App() {
  const [showing, setShowing] = useState(false);
  const onClick = () => {
    setShowing(prev => !prev)
  }
  return (
    <div>
      {/* 자바스크립트 쓸 때는 중괄호 쳐야함 */}
      {showing ? <Hello /> : null}
      <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
    </div>
  );
}

export default App;
 
 
가장 흔히 쓰이는 모양
import { useState, useEffect } from "react";    // 한번에 여러개를 같은 곳에서 import 할 때 이렇게 할 수도 있나보다

function Hello(){  
  useEffect(() => {
    console.log("hi :)");
    return () => {
      console.log("bye :(");
    }
  }, []);

  /*  // 위의 코드와 같으나, 더 길어서 선호되지는 않음
  useEffect(function(){
    console.log("hi :)");
    return function(){
      console.log("bye :(");
    }
  }, []);
  */
  return <h1>Hello</h1>
}

function App() {
  const [showing, setShowing] = useState(false);
  const onClick = () => {
    setShowing(prev => !prev)
  }
  return (
    <div>
      {/* 자바스크립트 쓸 때는 중괄호 쳐야함 */}
      {showing ? <Hello /> : null}
      <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
    </div>
  );
}

export default App;
 
 
이론은 끝났다고 함.
다음 강의부터는 프로젝트, 연습
profile

newChobo

@새로운뉴비

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!