티스토리 뷰

what i learned/TIL

[TIL] 2022/01/05 Wed -

zubetcha 2022. 1. 5. 22:35

 

 

 

 

 

Today I Learned

 

 

어제까지 큼직한 기능 구현들을 끝내고 오늘은 본격적으로 자잘한 것들을 수정하기 시작했다.

 

 

 퀴즈 결과 로직 

 

유저가 퀴즈 10문제를 풀면서 선택한 답은 컴포넌트 안에서 state로 관리하는 게 아닌 리덕스에 저장되도록 설정했다.

그래서 퀴즈 결과 페이지에서는 아래 세 가지 재료를 가지고 화면에 결과를 띄울 수 있도록 간단하게 로직을 만들었다.

 

1. 유저가 선택한 답 

2. 퀴즈 문제 및 정답

3. 결과 출력 

 

/* QuizResult.js */
/* 생략 */

/* 유저가 선택한 답은 리덕스에서 꺼내오기 */
const user_answer_list = useSelector((state) => state.quiz.user_answer_list)

/* 부모 컴포넌트에서 props로 넘겨 받은 퀴즈 데이터에서의 정답과 유저가 선택한 답 매치 -> 맞힌 개수 도출 */
const answerCnt = quiz_list
  ? quiz_list.filter((quiz, i) => {
    return quiz.solution === user_answer_list[i]
  }).length
: null

/* 맞힌 개수에 따라 출력할 멘트 state로 설정 */
const [resultText, setResultText] = useState({ sub: '', main: '' })

/* 퀴즈 결과 컴포넌트가 렌더링 될 때 한 번만 resultText state 설정 */
useEffect(() => {
  if (answerCnt >= 0 && answerCnt < 4) {
    setResultText({ sub: '아주 작은 기적...', main: '"밈기적."' })
  } else if (answerCnt >= 4 && answerCnt < 8) {
    setResultText({ sub: `${answerCnt}개나 맞춘 나,`, main: '제법 "밈잘알"이에요.' })
  } else {
    setResultText({ sub: '치료가 필요할 정도로 심각한', main: '"밈 중독"입니다.' })
  }
}, [])

/* 생략 */

 

 

 styled-components의 themeProvider 설정 

 

처음에 파일은 만들어뒀는데 계속 내용 설정을 못하고 있다가

전체적인 CSS 작업에 들어가게 되면서 확정된 요소들만 세팅했다.

 

적용 방법은 매우 간단하다.

 

1. theme.js 에 세팅하고자 하는 CSS 속성들을 객체로 만든다.

2. 실행 파일에서 ThemeProvider와 theme.js를 임포트한다.

3 ThemeProvider에 theme을 props로 넘겨준 후 최상위 컴포넌트로서 나머지 하위 컴포넌트들을 감싸준다.

 

/* theme.js */

// 반응형 디자인을 위한 픽셀 컨버팅 함수
const pixelToRem = (size) => `${size / 16}rem`

// font size를 객체로 반환해주자.
const fontSizes = {
  small: pixelToRem(9),
  base: pixelToRem(12),
  lg: pixelToRem(14),
  xl: pixelToRem(16),
  xxl: pixelToRem(18),
}

// 자주 사용하는 색을 객체로 만들자.
const colors = {
  black: '#000000',
  white: '#FFFFFF',
  yellow: '#FFE330',
  blue: '#00A0FF',
  orange: '#FF8E00',
  grey: '#878C92',
  line: '#E5E5E5',
}

// 자주 사용하는 스타일 속성을 theme으로 만들어보자.
const common = {
  flexCenter: `
    display: flex;
    justify-contents: center;
    align-items: center;
  `,
  flexCenterColumn: `
    display: flex;
    flex-direction: column;
    justify-contents: center;
    align-items: center;
  `,
}

// theme 객체에 감싸서 반환한다.
const theme = {
  fontSizes,
  colors,
  common,
}

export default theme

 

/* App.js */

import { ThemeProvider } from 'styled-components'
import theme from './styles/theme'

function App() {
  return (
    <>
      <ThemeProvider theme={theme}>
        /* GlobalStyle을 함께 사용하는 경우 ThemeProvider의 하위에 들어가야 한다. */
        <GlobalStyle />
        <ConnectedRouter history={history}>
          {하위 페이지 컴포넌트들}
        </ConnectedRouter>
      </ThemeProvider>
    </>
  )
}

export default App

 

 

 로그인 필요/불필요 페이지 랜딩 처리 

 

우리 조가 만드는 서비스는 컨텐츠를 소비하는 성격이 강하기 때문에

로그인을 하지 않고도 이용할 수 있는 페이지의 구분이 필요했고

url을 직접 입력하여 접근하는 경우도 고려해서 랜딩 시 어떻게 처리할지 고민하다 이전 기수의 커스텀 훅을 채용했다.

 

로컬 저장소에 유저 정보와 토큰이 존재하는 지에 따라 로그인 여부를 확인하고,

1) 로그아웃 상태인데 로그인이 필요한 페이지에 있는 경우 > 로그인 페이지로 이동

2) 로그인 상태인데 로그인 페이지 또는 로그인 랜딩 페이지에 있는 경우 > 메인페이지로 이동시킨다.

 

파라미터로는 페이지 컴포넌트 자체와 로그인이 필요한지, 불필요한지를 설정하는 불리언을 받아서

이 커스텀 훅을 실행 js 파일에 임포트한 후 아래 형태와 같이 작성해주면 된다.

 

/* App.js */

import Auth from './shared/auth'

function App() {
  return (
    <>
      <ThemeProvider theme={theme}>
        <GlobalStyle />
        <ConnectedRouter history={history}>
          <MobileFrame>
            <Route path="/" exact component={Main} />
            <Route path="/join" exact component={Auth(Join, false)} />
            <Route path="/login" exact component={Auth(Login, false)} />
            <Route path="/mypage" exact component={Auth(Mypage, true)} />
            <Route path="/quiz" exact component={QuizIntro} />
            <Route path="/quiz/:category" exact component={Quiz} />
            <Route path="/quiz/:category/result" exact component={QuizResult} />
            /* 생략 */
          </MobileFrame>
        </ConnectedRouter>
      </ThemeProvider>
    </>
  )
}

export default App

 

로그인, 회원가입 페이지는 너무나 당연하게 로그인이 필요 없는 페이지이기 때문에 false,

마이페이지는 로그인 상태여야 접근이 가능한 페이지이기 때문에 true,

퀴즈는 로그인을 하지 않아도 접근할 수 있어야 하기 때문에 인증 커스텀 훅을 사용하지 않는다.

 

사실 로그인이 필요 없으면 아예 훅을 사용하지 않으면 되지만, 

로그인, 회원가입 페이지는 불리언에 따라 랜딩 시 다른 페이지로 이동을 시켜줘야 하기 때문에 false로 설정하였다.

 

 

그 외에는 자잘한 css 디테일 작업을 하였다.

팀원들마다 스타일을 적용하는 방법이 제각각이라서 나중에 리팩토링할 때 꽤나 애먹을 것 같다는 생각이 들었다.

 

 

 

링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Total
Today
Yesterday