state and effect practice

Juyeon Lee·2022년 5월 19일
0

REACT 리액트

목록 보기
38/65
import React from "react"
import WindowTracker from "./WindowTracker"

export default function App() {
    /**
     * Challenge:
     * 1. Create state called `show`, default to `true`
     * 2. When the button is clicked, toggle `show`
     * 3. Only display `<WindowTracker>` if `show` is `true`
     */
    
    const [show, setShow] = React.useState(true)
    
    function toggle() {
        setShow(prevShow => !prevShow)
    }
    
    return (
        <div className="container">
            <button onClick={toggle}>
                Toggle WindowTracker
            </button>
            {show && <WindowTracker />}
        </div>
    )
}

challenge에 따라 show state잘 만들어주었고
버튼 누르면 작동되는 함수도 만들어줌
배웠던 &&도 잘 사용할 수 있었다.
물론 이것도 처음에는 혼자서 못했지만
한 번 강의 듣고 다시 하니까 혼자 구현가능했음

지금 토글로 windowTracker가 나왔다 안나왔다 이렇게 구현했는데
안나오게 했을 경우에는 unmounted라고 해서
dom에서 사라진다고 한다.
이럴 경우에는 react 밖에서 일어나는 일들을
관여하는거니까 useEffect를 써주면 된다.

이거에 관한 challenge가 다음에 있었는데
아래의 코드를 살펴보자

import React from "react"

export default function WindowTracker() {
    /**
     * Challenge:
     * 1. Create state called `windowWidth`, default to 
     *    `window.innerWidth`
     * 2. When the window width changes, update the state
     * 3. Display the window width in the h1 so it updates
     *    every time it changes
     */
    
 const [windowWidth, setWindowWidth] = React.useState(window.innerWidth)
    
    React.useEffect(() => {
        window.addEventListener("resize", function() {
            setWindowWidth(window.innerWidth)
        })
    }, [])
    
    return (
        <h1>Window width: {windowWidth}</h1>
    )
}

저렇게 useEffect 안에 이벤트 리스터 추가해주고 function 추가해줌
근데 여기서 이 코드의 문제점이 unmounted된 상황에서도
eventListener를 윈도우에서 해주려고 한다고 함
그래서 이렇게 되면 버그임...그 버그를 memory leak이라고 한다.

import React from "react"

export default function WindowTracker() {
    
    const [windowWidth, setWindowWidth] = React.useState(window.innerWidth)
    
    React.useEffect(() => {
        function watchWidth() {
            console.log("Setting up...")
            setWindowWidth(window.innerWidth)
        }
        
        window.addEventListener("resize", watchWidth)
        
        return function() {
            console.log("Cleaning up...")
            window.removeEventListener("resize", watchWidth)
        }
    }, [])
    
    return (
        <h1>Window width: {windowWidth}</h1>
    )
}

function에 이름 붙여준다음에 일단 빼줬고
window.removeEventListener("resize", watchWidth)
이렇게 써서 clearing해줬다. 아 그위에 return했다는게 중요하다!
이렇게 하면 위에 썼던 문제점이 해결된다고 한다.

흠 그리고 지금까지 했던 방식와 다르게 async을 쓰고 싶다면
아래와 같이 하면 된다고 함..
자바스크립트 api에 관해서 아직 많이 부족한거 같다.. ㅠㅠ
분명히 공부했는데 긴가민가함..다시 자바스크립트 이쪽 부분 공부해야겠음.

useEffect takes a function as its parameter. If that function
returns something, it needs to be a cleanup function. Otherwise,
it should return nothing. If we make it an async function, it
automatically retuns a promise instead of a function or nothing.
Therefore, if you want to use async operations inside of useEffect,
you need to define the function separately inside of the callback
function, as seen below:
  React.useEffect(() => {
        async function getMemes() {
            const res = await fetch("https://api.imgflip.com/get_memes")
            const data = await res.json()
            setAllMemes(data.data.memes)
        }
        getMemes()
    }, [])

0개의 댓글