• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 state 관련 질문드립니다!

state 관련 질문드립니다!

6 글 보임 - 1 에서 6 까지 (총 6 중에서)
  • 글쓴이
  • #20756

    고은찬
    참가자

    안녕하세요 코딩애플님
    소켓 IO를 통해 서버에서 받은 데이터를 state로 저장해서 사용하고 싶은데
    다른 함수에서 저장한 state값을 사용하려니 계속 받은 데이터가 아닌 useState()로 생성할때 만든 초기값을 가져와
    잘 이해가 안되서 글 남깁니다.

    아래는 현 상황 예시 코드 입니다.

     

    const [name,set_name] = useState("처음이름")

    1. 함수 first() 에서 소켓 IO 를 통해 데이터를 받고, 받은 데이터를 state 에 저장 (소켓통신은 문제없이 잘 됨)

    socket.on('connect',data =>{
    console.log(data.name) // 홍길동
    first(data.name)
    })

    const first = (data) = > {

    // name에 "홍길동"을 넣어줌
    set_name(data.name)
    }

     

     

    2. 함수 second() 에서 "name" state 값에 따라 분기 처리 하고싶음

    const second= ( )=> {

    console.log(name) // 값 : "처음이름"

    if (name==="홍길동" ) {
    ` console.log("안녕하세요 멋지시네요")

    }else if(name==="김태희"){
    console.log("안녕하세요 예쁘시네요")
    } ...

    }

     

     

    함수 second() 에서 name state를 로그 찍어보면
    first() 함수에서 set_name 한 "홍길동" 이 아닌
    name state를 생성할때 만든 값인 "처음이름" 이 찍힙니다.

    왜 그런지 잘 모르겠습니다 ㅠㅠ
    이유를 알려주시면 감사하겠습니다!

    #20767

    codingapple
    키 마스터

    if문이 웹소켓에서 데이터 가져온 후에 실행되는게 아니라

    먼저 실행되고 있어서 그런 것이 아닐까요

    데이터 받아오면 if문 실행해달라고 코드를 짜봅시다 

    #20780

    고은찬
    참가자

    처음 first()에서  set_name(data.name) 이후 컴포넌트의 return() 부분 (JSX) 에서 

    return(

    <div>{name}</div>

     )

    해보면 화면에 홍길동 으로 잘 출력되는거 보면 그건 아닌거 같아서요 ㅠㅠ 

    좀 더 정확한 코드를 올려봐도 괜찮을까요? 

    #20790

    고은찬
    참가자

    원인을 파악했습니다! useEffect가 문제였는데요

    서버에서 온 소켓 이벤트를 듣는 부분이 useEffect 안에 들어가 있는데 이때 useEffect에 빈 의존성 배열을 사용하고 있습니다.

    왜냐하면 의존성 배열 없이 사용하거나 useEffect 밖에서 사용하면 서버에서 오는 소켓 이벤트리스너가 여러개 생성되어 로직에 문제를 일으켰습니다. (<-소켓 이벤트를 수십번씩 받음)

    그래서 검색해보니 서버에서 소켓 이벤트가 왔을때만 실행되도록 하려면 빈 의존성 배열을 넣어 해결가능하다는 자료를 보고 그렇게 적용해서 해결했었습니다.

    (자료 링크 : https://rossbulat.medium.com/react-hooks-managing-web-sockets-with-useeffect-and-usestate-2dfc30eeceec)
    ( ctrl+f 로 "/only re-run the effect if new message comes in" 검색)

    그런데 이렇게 되면 이 안에서 state 가 를 사용하는 함수 사용시 초기 랜더링 시 값(useState의 초기값) 만 불러오기 때문에 적용이 안되는 거였습니다.

    코드를 다시 보여드리면

    const [name,set_name] = useState("처음이름")
    // 서버에서 온 소켓 이벤트를 듣는 부분
    // first 이벤트 받아온 이후 서버에서 바로 second 실행됨
    useEffect( () => {
    socket.on('connect',data =>{

    switch (data.id) {
    case : first
    set_name("홍길동")
    break;
    case : second
    console.log(name) // 값 : 처음이름
    break;

    case : third...(말고도 많은 case문 존재)
    break;

    default :
    break;
    }
    })
    },[]) //only re-run the effect if new message comes in <-----이 부분이 문제

    그렇다고 저 의존성 배열 안에 name을 넣으면 로그에
    1) 처음이름
    2) 홍길동
    이렇게 값이 들어오긴합니다.

    대신 서버에서 소켓이벤트를 받을때마다 useEffect안의 모든것이 2번씩 실행 되구요

    2번씩 되는것도 비효율적이라 생각해서..

    소켓이 올때마다 이벤트는 한번만 들으면서 업데이트된 name state의 값을 사용하고 싶은데 어떻게 해야 할까요??? 도와주십시오 ㅠㅠ

    #20792

    고은찬
    참가자

    텍스트로 하니 보기 힘들어서 캡쳐 이미지로 올립니다! 
    질문은 사진 안 주석 보시면 됩니다! 감사합니다

    글 속 자료 링크 : https://rossbulat.medium.com/react-hooks-managing-web-sockets-with-useeffect-and-usestate-2dfc30eeceec)

    111

    222

     

    #20799

    codingapple
    키 마스터

    <React.StrictMode> 이거 있으면 useEffect안의 코드가 2번 실행될 수 있습니다

    개발시 디버깅용도라서 제거해보거나 그러면 됩니다 

6 글 보임 - 1 에서 6 까지 (총 6 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관, 개인정보처리방침
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠