pwa 웹앱 적용을 위해서 service-worker가 반드시 필요했다. 하지만 우리 앱의 특성 상 상수로 가져와야 하는 데이터가 많지 않았고, 오히려 유저의 사용에 따라 계속 데이터가 변경되는 페이지들이 더 핵심 기능이었다. 때문에 캐싱을 요긴하게 쓸만한 영역이 없을것이라 생각했다.
새로고침을 하면 redux의 state 데이터는 날아가게 됨... 그런데 우리 앱의 특성 상 페이지가 넘어가면서 redux state를 그대로 이용해야 하는 경우가 많았는데, 특정 페이지에서 새로고침을 하면 데이터 에러가 나게 됨. 사용하려는 데이터가 undefined라던지 null이라던지...


// App.js
...
return (
    <ErrorBoundary>
      ...
    </ErrorBoundary>
  );
// ErrorBoundary.js
...
class ErrorBoundary extends Component {
  state = {
    error: false,
  };
  componentDidCatch(error, info) {
    logger('에러가 발생했습니다.');
    logger({
      error,
      info,
    });
    this.setState({
      error: true,
    });
    if (process.env.NODE_ENV === 'production') {
      Sentry.captureException(error, { extra: info });
    }
  }
  render() {
    if (this.state.error) {
      return (
        <Cont>
          <ImgContainer src={LoginBackground}></ImgContainer>
          <Text
            type="contents"
            textAlign="center"
            fontSize="18px"
            fontWeight="500"
          >
            찾으시는 데이터가 없습니다.
          </Text>
          <Text
            type="contents"
            textAlign="center"
            fontSize="15px"
            fontWeight="500"
          >
            메인으로 돌아가기
          </Text>
          <Image
            src={Home}
            width="40px"
            height="40px"
            _onClick={() => {
              history.replace('/');
              window.location.reload();
            }}
          />
        </Cont>
      );
    }
    return this.props.children;
  }
}
export default ErrorBoundary;
// configStore.js
...
import { persistStore } from 'redux-persist';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import Exercise from './modules/exercise';
import User from './modules/user';
import Challenge from './modules/challenge';
import Feed from './modules/feed';
import Calendar from './modules/calendar';
export const history = createBrowserHistory();
const rootReducer = combineReducers({
  exercise: Exercise,
  user: User,
  feed: Feed,
  challenge: Challenge,
  calendar: Calendar,
  router: connectRouter(history),
});
const persistConfig = {
  key: 'root',
  storage,
  whitelist: ['exercise', 'challenge', 'feed'],
};
const enhancedReducer = persistReducer(persistConfig, rootReducer);
const middlewares = [thunk.withExtraArgument({ history: history })];
...
const composeEnhancers =
  typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
      })
    : compose;
const enhancer = composeEnhancers(applyMiddleware(...middlewares));
let store = (initialStore) => createStore(enhancedReducer, enhancer);
export default store();
// index.js
ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
  document.getElementById('root'),
);