14-6. 새 데이터 로딩 방지 및 유저네임 바뀌면 리로딩
지금 프로젝트 상태에서, 발생 할 수 있는 두가지 버그가 있습니다. 한가지는, 유저페이지를 보고 있을 때 다른 유저가 포스트를 작성하게 되면 리스트에 신규 포스트가 뜬다는 점과, 유저페이지를 보다가 덧글을 통하여 다른 유저의 페이지로 넘어가게 됐을때, 리로딩이 되지 않는 점 입니다.
새 데이터 로딩 방지
새 데이터 로딩 방지를 하기 위해서는, 소켓을 조금 수정해주어야합니다. 함수에서, _listen
이라는 변수를 정의하고, 이 값이 false 일 때는 리덕스에 액션을 디스패치 하지 않도록 설정을 하세요.
그리고 함수가 리턴하는 객체내부에서, listen
함수와 ignore
함수를 정의하세요.
src/lib/socket.js
export default (function socketHelper() {
let _store = null;
let _socket = null;
let _uri = null;
let _listen = true;
const listener = (message) => {
if(!_listen) return; // _listen 이 활성화가 되어있지 않으면 무시
const data = parseJSON(message.data); // JSON 파싱
if(!data || !data.type) return; // 파싱 실패했거나, type 값이 없으면 무시
_store.dispatch(data); // 제대로 된 데이터면 store 에 디스패치
}
const reconnect = () => {
// 연결이 끊겼을 때 3초마다 재연결
console.log('reconnecting..');
setTimeout(() => connect(_uri), 3000);
}
const connect = (uri) => {
_uri = uri;
_socket = new WebSocket(uri);
_socket.onmessage = listener;
_socket.onopen = (event) => {
console.log('connected to ' + uri);
}
_socket.onclose = reconnect; // 연결이 끊기 면 재연결 시도
}
return {
initialize: (store, uri) => {
_store = store;
connect(uri);
},
listen: () => {
_listen = true;
},
ignore: () => {
_listen = false;
}
}
})()
그 다음에는, User 페이지가 마운트 될 때 / 언마운트 될 때 ignore 혹은 listen 함수를 호출하면 됩니다.
src/pages/User.js
(...)
import socket from 'lib/socket';
class User extends Component {
componentDidMount() {
socket.ignore();
}
componentWillUnmount() {
socket.listen();
}
render() {
(...)
}
}
export default User;
이렇게 하면 첫번째 버그가 수정됩니다.
유저네임 바뀌면 리로딩
User 페이지에서 다른 User 페이지로 넘어갈때에는, 같은 라우트이기 때문에 componentDidMount 가 다시 실행되지 않습니다. match.params 만 변경이 되는 것이기 때문에, 컴포넌트가 리렌더링됩니다. 따라서, 그 자식 컴포넌트인 PageListContainer 컴포넌트도 다시 마운트 되는것이 아니라, username props 만 업데이트가 되는것이죠.
유저네임이 바뀌었을때 리로딩이 되지 않는 현상을 고치러면 componentDidUpdate 에서 처리를 해주어야합니다.
PageListContainer 컴포넌트에서 componentDidMount 메소드를 다음과 같이 추가하세요.
src/containers/Shared/PostList/PostListContainer.js
- componentDidMount
componentDidUpdate(prevProps, prevState) {
// username 이 변경되면 this.load 를 호출합니다
if(prevProps.username !== this.props.username) {
this.load();
}
}