상세 컨텐츠

본문 제목

[Next] 대충프로젝트(3) - useEffect 의존성 배열 제대로 사용하기

프로젝트 정리/대충

by 래모 2023. 5. 12. 22:38

본문

거의 한달동안 고치지 못한 오류를 드디어 고친 기념!

블로그 포스팅으로 남겨두려고 한다


코드에서 recoil을 사용하여 전역으로 사용하는 변수인 change가 있다.

이 change의 초기값은 false이며 어떤 값들이 post, delete, put되면 prev=>!prev로 설정해서

이전과 다른 값이 되도록 설정한다

 

useEffect는 이 값을 감지하여 데이터를 다시 가져오는데

여기서!!!! 데이터가 바로 가져와지지 않는 오류가 발생했었다

즉 change가 바뀌는 것을 useEffect가 알아차리지 못 하는 것...

 

이걸 거의 한달 동안 끙끙거리며 고치지 못했었다

 

처음 생각한 방법은 값이 변경될 때는 현 컴포넌트에서 하위 컴포넌트에서 변경되므로

그 밑으로 함수를 넘기고 이것을 상위 컴포넌트가 감지하는 식으로 사용했다.(아래 블로그 참고)

 

https://velog.io/@onezerokang/%ED%95%98%EC%9C%84-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EA%B0%80-%EC%83%81%EC%9C%84-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%A1%9C-%EA%B0%92%EC%9D%84-%EC%A0%84%EB%8B%AC%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95

 

하위 컴포넌트가 상위 컴포넌트로 값을 전달하는 방법

React를 사용하다보면 상위 컴포넌트에서 하위 컴포넌트로 값을 넘겨줄 때가 많다. 그럴 때 보통 props를 사용한다. 하지만 하위 컴포넌트에서 상위 컴포넌트로 값을 넘겨줄 때는 props로 넘겨줄 수

velog.io

 

하지만...처참히 실패.... 이래도 알아차리지 못 했다

 

열심히 구글링과 챗지피티에게 물어본 결과!

 

Recoil은 React의 state와는 다르게 별도의 라이브러리로 관리되며, 상태가 변경될 때 React의 setState 함수를 직접 호출하지 않습니다. Recoil은 내부적으로 state가 변경될 때마다 구독자에게 알림을 보내는 방식을 사용합니다. 이렇게 Recoil이 관리하는 state가 변경되었을 때 React가 자동으로 리렌더링을 하도록 하려면, useRecoilState나 useRecoilValue 훅을 사용하여 Recoil state를 감시해야 합니다.

따라서, useEffect의 의존성 배열에 Recoil state가 아니라, Recoil state를 변경할 수 있는 함수를 의존성 배열에 추가하여 Recoil state가 변경될 때 useEffect가 실행되도록 해야 합니다.

!!!한줄기 빛과 같은 답변이었다

지피티의 말대로 코드를 아래와 같이 수정해주었다

 

//noteCreate.js
...
const [change, setChange] = useRecoilState(changeState)
...
const onValid = (data) => {
        console.log(data.files)
        const formData = new FormData();
        formData.append('content', data.content);
        console.log(formData)
        if (Array.from(data.files).length !== 0 ){
            Array.from(data.files).map(f=>formData.append('file', f))
        }
        
         axios({
            method:"post",
            url:`${process.env.NEXT_PUBLIC_API_URL}/notes/small-cate-id/${sCateId}`,
            headers:{
                'Content-Type': 'multipart/form-data',
            },
            data:formData
        }).then(res=>{
            console.log("notecreate",res)
            setChange(prev=> !prev)//!!바꿔줌!!
        })
        .catch(err=>console.log(err)) 
        reset() 
        setPreviewImg([])
        
        console.log("체인지",change)
        
    }//노트가 submit될 때 불러와지는 함수
//notes/[...cate].js
...
useEffect(()=>{
        if (isInitialMount){
            setIsInitialMount(false)
        } else {
            const axiosData = () => {
                 axios({
                    method:"get",
                    url:url,
                }).then(res=>{
                    setNotes(res.data.notes)
                    console.log(res.data.notes)
                })
                .catch(err=>console.log(err))
            }
            
            axiosData()
        }
        
    },[url, isInitialMount,axios, sequence,setSequence, change,setChange]) //setChange를 써주는 것이 중요!!

 

이러면 useEffect가 change값이 변경될 때마다 감지하여 데이터를 다시 fetch해온다

 

관련글 더보기