🌈화면 구현

NavBar 컴포넌트 구현

<aside> ❓

a VS Link VS NavLink

https://ramincoding.tistory.com/entry/React-React-Router-NavLink-컴포넌트-VS-Link-컴포넌트

Link 컴포넌트는 a 태그와 유사하지만, 페이지 전환을 방지함 (CSR 처리 가능)

NavLink 컴포넌트는 조건부 로직 처리 편리, 웹 접근성 향상

</aside>

<aside> ❓

NavLink 컴포넌트

https://velog.io/@eunji9128/Active-Links

https://www.heropy.dev/p/9tesDt

<NavLink to="/">Home</NavLink> // alway active
<NavLink to="/" end>Home</NavLink> // only active at "/"

</aside>

import BoardPage from './pages/board/BoardPage'
import Fonts from './styles/fonts'
import { Route, Routes } from 'react-router-dom'

function App() {
  return (
    <>
      <Fonts />
      **<Routes>
        <Route path="/board" element={<BoardPage />} />
      </Routes>**
    </>
  )
}

export default App
import tw from 'twin.macro'
import { PiClipboardText } from 'react-icons/pi'
import { colors } from '@/styles/colors'
import { NavLink } from 'react-router-dom'

const NavContainer = tw.div`
  flex justify-between items-center px-4 pt-3 pb-8 border-t border-t-gray
`

export default function NavBar() {
  return (
    <NavContainer>
...
      {/* Board */}
      **<NavLink
        to="/board"
        style={({ isActive }) => ({
          color: isActive ? colors.default : colors.darkGray,
        })}
      >
        <PiClipboardText size="2rem" />
      </NavLink>**
...
    </NavContainer>
  )
}

게시글 상세페이지 이동 구현

1. App.tsx에 Route 추가

<Route path="/board/:postId" element={<BoardDetailPage />} />

⭐ 아래 2, 3 단계 대신 BoardCard.tsx에 Link 컴포넌트 추가로 통합

interface BoardCardProps {
  **id: number**
  status: string
  title: string
  authorNickname: string
  date: string
  chstCount?: number
  thumbnailUrl: string
}

export default function BoardCard({
  **id,**
  status,
  title,
  authorNickname,
  date,
  chstCount,
  thumbnailUrl,
}: BoardCardProps) {
  const badgeData = getBadgeData(status)

  return (
    **<Link to={`/board/${id}`}>**
      <CardContainer>
      ...
      </CardContainer>
    </Link>
  )
}

2. BoardPage.tsx에 BoardCard 컴포넌트 클릭 시 경로 이동 추가

import { useNavigate } from 'react-router-dom'
import tw from 'twin.macro'

...

export default function BoardPage() {
  **const navigate = useNavigate()

  const handleCardClick = (postId: number) => {
    navigate(`/board/${postId}`) // 게시글 상세 페이지로 이동
  }**

  return (
    <Container>
      <SubHeader title="견적게시판" />
      {/* SECTION -  게시글 리스트 영역 */}
      <ScrollArea>
        **{posts.map((item) => (
          <BoardCard
            key={item.id}
            {...item}
            onClick={() => handleCardClick(item.id)}
          />
        ))}**
      </ScrollArea>
      <NavBar />
      {/* SECTION - 글쓰기 버튼 */}
      <BoardWriteBtn />
    </Container>
  )
}

3. BoardCard.tsx 컴포넌트에 클릭 함수 추가

interface BoardCardProps {
  id: number
  status: string
  title: string
  authorNickname: string
  date: string
  chstCount?: number
  thumbnailUrl: string
  **onClick: () => void**
}

export default function BoardCard({
  status,
  title,
  authorNickname,
  date,
  chstCount,
  thumbnailUrl,
  **onClick,**
}: BoardCardProps) {
  const badgeData = getBadgeData(status)

  return (
    <CardContainer **onClick={onClick}**>
      ...
    </CardContainer>
  )
}

4. BoardDetailPage.tsx 화면 UI 구현

import NavBar from '@/components/NavBar'
import { useParams } from 'react-router-dom'
import tw from 'twin.macro'

...

export default function BoardDetailPage() {
  **const { postId } = useParams()** *// /board/:postId와 동일한 변수명으로 데이터 꺼내기 가능*

  return (
    <Container>
    ...
      {/* SECTION - 게시글 상세 영역 */}
      <ScrollArea></ScrollArea>
      <NavBar />
    </Container>
  )
}