14-3. 유저 프로필 조회하기
이번 섹션에서는 기존에 만들었던 유저 프로필 조회 API 인 /api/users/:username 를 통하여, 유저의 프로필 정보를 가져와서 UserHead 에 전달하는 작업을 하겠습니다.
API 함수 만들기
유저 프로필 정보 조회 API 를 요청하는 함수를 users.js 파일에 준비하세요.
src/lib/api/users.js
import axios from 'axios';
export const getUserInfo = (username) => axios.get(`/api/users/${username}`);
userPage 리덕스 모듈 만들기
기존의 로그인한 사용자의 정보를 담는 user 모듈과 혼동 될 수 있으니, userPage 라는 이름으로 리덕스 모듈을 생성하세요.
GET_USER_INFO
라는 액션을 만들어서, 요청이 성공하면 info 라는 Map 에 유저정보를 담도록 코드를 작성하세요.
src/redux/modules/userPage.js
import { createAction, handleActions } from 'redux-actions';
import { Map, fromJS } from 'immutable';
import { pender } from 'redux-pender';
import * as UsersAPI from 'lib/api/users';
const GET_USER_INFO = 'userPage/GET_USER_INFO';
export const getUserInfo = createAction(GET_USER_INFO, UsersAPI.getUserInfo);
const initialState = Map({
info: Map({
profile: Map({
thumbnail: null,
username: null
}),
thoughtCount: null
})
});
// reducer
export default handleActions({
...pender({
type: GET_USER_INFO,
onSuccess: (state, action) => state.set('info', fromJS(action.payload.data))
})
}, initialState);
리덕스 모듈을 만든 다음에는 방금 만든 모듈을 modules 인덱스 파일에 추가하세요.
src/redux/modules/index.js
import { combineReducers } from 'redux';
import base from './base';
import auth from './auth';
import user from './user';
import home from './home';
import posts from './posts';
import userPage from './userPage';
import { penderReducer } from 'redux-pender';
export default combineReducers({
base,
auth,
user,
home,
posts,
userPage,
pender: penderReducer
});
UserHeadContainer 완성하기
이제 UserHeadContaine 컴포넌트를 리덕스에 연결시켜서 필요한 상태를 연결시켜주고 또 액션도 디스패치하겠습니다.
getUserInfo
라는 메소드를 정의하고, 이 메소드를 컴포넌트가 마운트가 될 때, componentDidMount 에서 호출하면 됩니다.
상태쪽에서 필요로 한 것은, thumbnail, thoughtCount 그리고 fetched 입니다. fetched 의 경우엔 redux-pender 리듀서의 success 객체를 참조하여, 우리가 호출한 액션 userPage/GET_USER_INFO
가 성공적으로 완료가 되었는지 여부를 확인합니다.
src/containers/User/UserHeadContainer.js
import React, { Component } from 'react';
import UserHead from 'components/User/UserHead';
import { connect } from 'react-redux';
import {bindActionCreators} from 'redux';
import * as userPageActions from 'redux/modules/userPage';
class UserHeadContainer extends Component {
getUserInfo = async () => {
const { UserPageActions, username } = this.props;
try {
UserPageActions.getUserInfo(username);
} catch (e) {
console.log(e);
}
}
componentDidMount() {
this.getUserInfo();
}
componentDidUpdate(prevProps, prevState) {
if(prevProps.username !== this.props.username) {
this.getUserInfo(); // 유저네임이 변경되면 새로 로딩
}
}
render() {
const { username, thumbnail, thoughtCount, fetched } = this.props;
if(!fetched) return null;
return (
<UserHead username={username} thumbnail={thumbnail} thoughtCount={thoughtCount}/>
);
}
}
export default connect(
(state) => ({
thumbnail: state.userPage.getIn(['info', 'profile', 'thumbnail']),
thoughtCount: state.userPage.getIn(['info', 'thoughtCount']),
fetched: state.pender.success['userPage/GET_USER_INFO']
}),
(dispatch) => ({
UserPageActions: bindActionCreators(userPageActions, dispatch)
})
)(UserHeadContainer);
그리고, fetched 값이 false 면 아무것도 렌더링하지 않고, true 면 우리가 받아온 정보를 보여줍니다.
여기까지 완성을 하고나면, 특정 유저의 페이지를 조회하게 될 때 썸네일과 갯수가 제대로 나타나게 됩니다.