본문 바로가기
React

React(45) 타입스크립트 - api 객체 받아오기 1 (상세페이지)

by 새발개발JA 2021. 9. 10.
반응형

 

 

 

리액트와 타입스크립트를 이용하여 api 객체를 받아오는 방법에 대한 포스팅 순서이다.

 

1. React(45) 타입스크립트 - api 객체 받아오기 (상세페이지) 1

   - api 로 서버에서 채팅방과 유저들의 정보를 받아와 회원 등급에 따른 채팅 리스트를 구현한다.

 

2. React(46) 타입스크립트 - api 객체 받아오기 (상세페이지) 2

   - 구현한 채팅 리스트를 바탕으로 채팅 정보가 들어있는 상세 페이지를 구현해보았다.


React(45) 타입스크립트 - api 객체 받아오기 (상세페이지)  - 1 

모든 것이 처음이었다. 타입스크립트도 낯설기만 하였다. 컴포넌트가 여러개 연결되다 보니 그냥 코딩만 할 수는 없었다.

처음으로 며칠동안 구조에 대해 고민하게 된 계기가 되기도 하였다. 왜 구조가 중요한지도 깨달았다.

 

결과 화면  

1. 통신메소드를 통해 컴포넌트 내에서 채팅방 리스트를 받아온다.  [ 더보기 ] 버튼을 누르자.

 

2. [ 더보기 ] 를 누르면 customer 인 유저 정보와 그에 따른 1:1 채팅방 리스트로 연결된다. (상세페이지)

** 실제 코드는 리팩토링하여 구조 자체가 바뀌었으며, 초반에 작업한 코드를 모두가 볼 수 있도록 수정하여 참고용으로 포스팅합니다. 혹시 맞지 않는 부분이 있더라도 부족한 코드 양해부탁드립니다 :)

 

App.tsx

라우팅 기능을 이용해 url  뒤가 /user 인 UserList 컴포넌트로 이동하자.

import { ReactElement } from 'react'
import { UserDetail } from 'pages'
import { UserList } from 'component/UserList'

const App = (): ReactElement => {

  return (
      <div className="app">
        <Route exact path="/user/" component={UserList} /> 
        <Route exact path="/user/:id" component={UserDetail} /> 
      </div>						// url에 ' /:id ' 를 넣으면 동적라우팅이 가능하다
  )
}
export default App

 

 

UserList.tsx

유저는 일반회원이 있고, 특별회원이 있다. [ 회원 버튼 ]을 누를 때마다 tab 에 유저 타입이 들어가면서 모든 분기 처리의 시작이 된다.

useEffect 가 [ 회원 버튼 ] 을 누를 때마다 렌더링되고 getList() 를 통해 tab 에 맞는 객체를 데려온다. 

import { ReactElement, useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { User } from 'model/User'
import UserItem from 'components/user/UserItem'
import http from 'util/HttpConfig'
import USER_TYPE from 'util/UserType'

const UserList = (): ReactElement => {
  const [tab, setTab] = useState(USER_TYPE.SPECAIL);	// tab 으로 회원 종류를 구분할 것이다
  const [loading, setLoading] = useState(false)		// 로딩 상태를 나타낸다.
  const [userList, setUserList] = useState<User[]>([])	// api 로 받은 유저객체들을 담을 변수

  useEffect(() => {						
    if (!loading) { 					// 로딩이 false 일 때, (즉 로딩 중이 아닐 때)
      getList();    					// 통신함수 getList()를 실행 
    }
  }, [tab]);						// 언제 실행하냐고? [탭]을 칠때마다~

  // api 객체 받아오는 통신 함수
  async function getList() {
    setUserList([]);  					// 유저리스트 초기화 (안그럼 에러남)
    setLoading(true); 					// 로딩은 true 로 변경한다

    try { 			// 통신 성공시, tab값에 따라 다른 객체를 받아 list 안에 저장한다
      const list = await http.get(`${api}/user?type=${tab}`);	
      
      if (list.status !== 200) { 			// 통신 시 에러 처리
        throw new Error(`Response status is "${list.status}"`);
      }

      if (list.data.resultData) { 			// list 로 데이터가 잘 저장되었으면
        const resList: User[] = JSON.parse( 		// resList에 list객체를 json형식으로 변환하자
          JSON.stringify(list.data.resultData)
        )
        setUserList(resList) 				// resList 를 userList 안에 저 ~ 장
      }
    } catch (e) { 		// 통신 실패시 예외 처리  
      alert('정보를 가져오는데 실패하였습니다.')   	// 안내 경고창과 함께
      console.error(e) 					// 콘솔에 에러 메시지 출력 
    }

    setLoading(false); 					// 통신 후 로딩은 다시 false 로 돌아감
  }

    return (
    <div className="user-list-wrap"> 
      <ul>
        <li
          className={tab === USER_TYPE.SPECIAL ? 'active' : ''}
          onClick={() => {				// 클릭하면 onClick 메소드에 의해
            setTab(USER_TYPE.SPECIAL);			// SPECIAL 타입이 tab에 저장된다.
          }}
        >
          특별회원
        </li>
        <li
          className={tab === USER_TYPE.GENERAL ? 'active' : ''}
          onClick={() => {				// 클릭하면 onClick 메소드에 의해
            setTab(USER_TYPE.GENERAL);			// GENERAL 타입이 tab에 저장된다.
          }}
        >
          일반회원
        </li>
      </ul>
      
      <div>
        
        <div>			  // 탭이 SPECIAL 이면 '특별'을 그렇지 않으면 '일반'이 보여진다.
          {tab === USER_TYPE.SPECIAL ? '특별회원' : '일반회원'}
        </div>   

        {userList.map(user => (   // 위에서 받아온 userList 객체를 map()로 돌려 컴포넌트를 출력하자
          <div>           
				
            <UserItem user={user} key={user.oid} />  // user객체들을 담아 <UserItem> 에 props로 보낸다.
            <Link to={`/user/${user.id}`} key={user.cid}>
              더보기				    // user의 id를 url 주소로 해당 페이지로 이동한다.
            </Link>
          </div>
        ))}
      </div>
    </div>
  );
}

export default UserList

 

 

 

 

 

 

반응형

댓글