πŸ“λ‹¨μΌ μ±…μž„ μ›μΉ™μœΌλ‘œ λ Œλ”λ§ κ°œμ„ (react next js)

Viking_JΒ·2024λ…„ 12μ›” 22일

😀 문제

β€œμ–΄λ–€ λ¬Έμ œκ°€ μžˆμ—ˆλ‚˜μš”β€

splitView λ‚΄μš©λ§Œ λ°”λ€ŒλŠ” 데 splitView μ»¨ν…Œμ΄λ„ˆκΉŒμ§€ λ¦¬λ Œλ”λ§ λœλ‹€.

🧐 문제 원인

β€œλ¬Έμ œ 원인이 λ¬΄μ—‡μΈκ°€μš”β€

splitView μ»¨ν…Œμ΄λ„ˆ μ—΄κ³  λ‹«λŠ” 둜직과 λ‚΄μš© λ°”κΎΈλŠ” 둜직이 같은 μ»΄ν¬λ„ŒνŠΈμ— μžˆλ‹€. κ·Έλž˜μ„œ λ‚΄μš©μ΄ λ°”λ€” λ•Œ μ»¨ν…Œμ΄λ„ˆ κΉŒμ§€ 리렝더링

😎 ν•΄κ²°μ±…

β€œν•΄κ²°μ±…β€

단일 μ±…μž„ μ›μΉ™μœΌλ‘œ splitView μ•ˆμ— λ‚΄μš©μ„ κ²°μ •ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈμ™€ splitView μ—΄κ³  λ‹«λŠ” μ»΄ν¬λ„ŒνŠΈλ‘œ λΆ„λ¦¬ν•œλ‹€.

πŸ€” 이유

β€œμ™œ 이런 ν•΄κ²°μ±… μ‚¬μš©ν–ˆλ‚˜μš”β€

splitView μ•ˆμ— λ‚΄μš©μ„ κ²°μ •ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ λΆ„λ¦¬λ˜λ©΄ μ•ˆμ— λ‚΄μš©μ΄ λ°”λ€Œμ–΄μ„ λ•Œ μ»¨ν…Œμ΄λ„ˆλŠ” 영ν–₯을 λ°›μ§€ μ•ŠλŠ”λ‹€.

  • splitViewContainer prop 가독성이 더 μ’‹μ•„μ‘Œλ‹€. 클린 μ½”λ“œ!

🀩 적용

β€œμ–΄λ–»κ²Œ μ μš©ν–ˆλ‚˜μš”β€

비포

//뢄리 μ „
import SecondaryViewContainer from "./SecondaryViewContainer "
function SplitViewContainer({ PrimaryView }: SplitViewContainerProp) {
  //μ—¬λŠ” 둜직
  const isOpen = useStoreSelector(splitViewStore, (state) => state.isOpen)
  //μ•ˆμ— λ‚΄μš© κ²°μ • 둜직
  const id = useStoreSelector(splitViewStore, (state) => state.id)
  const Content = id != null ? ssulContents[id] : () => null

  return (
    <div className="relative flex size-full justify-end">
      <div
        className={`absolute size-full lg:w-3/6 ${
          isOpen ? 'lg:left-0' : 'lg:left-1/2 lg:-translate-x-1/2'
        } overflow-y-scroll transition-all duration-300 ease-out`}
      >
        {PrimaryView}
      </div>
      {isOpen && (
        <div className="size-full animate-slide-in-right lg:w-5/12">
          <SecondaryViewContainer>
            <Content />
          </SecondaryViewContainer>
        </div>
      )}
    </div>
  )
}

μ• ν”„ν„°

//μ»¨ν…Œμ΄λ„ˆ(μ—΄κ³  λ‹«λŠ” 둜직만 λ‹΄λ‹Ή)
function SplitViewContainer({
  PrimaryView,
  SecondaryView,
}: SplitViewContainerProp) {
  const isOpen = useStoreSelector(splitViewStore, (state) => state.isOpen)

  return (
    <div className="relative flex size-full justify-end">
      <div
        className={`absolute size-full lg:w-3/6 ${
          isOpen ? 'lg:left-0' : 'lg:left-1/2 lg:-translate-x-1/2'
        } overflow-y-scroll transition-all duration-300 ease-out`}
      >
        {PrimaryView}
      </div>
      {isOpen && (
        <div className="size-full animate-slide-in-right lg:w-5/12">
          {SecondaryView}
        </div>
      )}
    </div>
  )
}
//μ»¨ν…νŠΈ (μ•ˆμ˜ λ‚΄μš©λ¬Ό κ²°μ • 둜직만 λ‹΄λ‹Ή)
function SecondaryViewContent({ id }: SecondaryViewContentProps) {
  const id = useStoreSelector(splitViewStore, (state) => state.id)
  const Content = id != null ? ssulContents[id] : () => null

  return (
    <article className="prose size-full !max-w-full py-5 md:prose">
      <Content />
    </article>
  )
}

λΆ„λ¦¬ν•˜κ³  λ‚˜λ‹ˆκΉŒ prop도 더 가독성이 μ’‹μ•„μ‘Œλ‹€.

//before
//μ„Έμ»¨λ”λ¦¬λ·°λŠ” 어딨지? 의문인 μ½”λ“œ
function Page() {
  return <SplitViewContainer PrimaryView={<PrimaryViewContainer/>} />
}
//after
//프라이머리 뷰와 세컨더리 λ·°κ°€ 각각 μ–΄λ–€ μ»΄ν¬λ„ŒνŠΈμ§€ μ•Œμˆ˜ μžˆλ‹€.
function Page() {
  return (
    <SplitViewContainer
      PrimaryView={<PrimaryViewContainer/>}
      SecondaryView={<SecondaryViewContainer/>}
    />
  )
}

λ Œλ”λ§ 갯수

비포: 5개

μ• ν”„ν„°: 4개

λ Œλ”λ§ μ‹œκ°„

비포: 5.7ms

μ• ν”„ν„°

λ Œλ”λ§ μ‹œκ°„ 3.3ms

profile
λͺ¨ν—˜μ„ λ– λ‚˜λ³΄μž

0개의 λŒ“κΈ€