이번 수업에서는 글을 선택했을 때만 update, delete 기능이 표시되도록 개선을 해보려고 합니다. 이 과정에서 server component에서 client component로 부분적으로 전환하는 방법을 익히게 될 것입니다.

소스코드
https://github.com/egoing/nextapp/commit/66de9dbd93cf1314b486c3ae06c4356940814bb6
절차
1. app/Control.js 생성
"use client"
import Link from 'next/link';
import { useParams } from 'next/navigation';
export function Control() {
const params = useParams();
const id = params.id;
return (
<ul>
<li><Link href="/create">Create</Link></li>
{id ? <>
<li><Link href={"/update/"+id}>Update</Link></li>
<li><input type="button" value="delete" /></li>
</> : null}
</ul>
);
}
2. Control 컴포넌트를 app/layout.js에서 사용
import Link from 'next/link'
import './globals.css'
import { Control } from './Control';
export const metadata = {
title: 'Web tutorial',
description: 'Generated by egoing',
}
export default async function RootLayout({ children }) {
const resp = await fetch('http://localhost:9999/topics', { cache: 'no-store' });
const topics = await resp.json();
return (
<html>
<body>
<h1><Link href="/">WEB</Link></h1>
<ol>
{topics.map((topic)=>{
return <li key={topic.id}><Link href={`/read/${topic.id}`}>{topic.title}</Link></li>
})}
</ol>
{children}
<Control />
</body>
</html>
)
}
server component 내에서는 현재 동적 라우팅의 값([id])을 layout 안에서는 알 수 없습니다. useParams를 사용해야 하는데 useParams는 client component입니다. app/layout.js 전체를 client component로 전환해도 됩니다만, server component의 이점을 포기하기는 싫기 때문에 여기서는 client component의 기능이 필요한 부분만 별도의 컴포넌트로 분리했습니다.

