이번엔 update와 delete 기능을 구현하기 전에 사전작업을 할 예정입니다.
글을 선택하고 있지 않은 상태에서는
Update와 delete 버튼이 보이지 않는게 맞을 겁니다.
반대로, 글을 선택하면 Update와 Delete버튼이 보여야할 것입니다.
Update버튼을 누르면 어디에 있든 Url 이 Update/1으로 이동하는데 그것이 아니라 해당 게시글의 id로 url이 변경되면 좋을 것 입니다.
//layout.js
<ul>
<li>
<Link href="/create">create</Link>
</li>
<li>
<Link href="/update/1">update</Link>
</li>
<li>
<input type="button" value="delete" />
</li>
</ul>
이 작업을 하기 위해서는 layout.js에서 url의 id가 있는지 없는지 체크해야합니다. 하지만 layout.js에서는 id가 있는지 없는지 확인할 수 없습니다.
그래서 read/[id]/page.js로 들어가서 확인해보겠습니다.
export default async function Read(props) {
const resp = await fetch(`http://localhost:9999/topics/
${props.params.id}`);
const topic = await resp.json();
return (
<>
<h2>{topic.title}</h2>
{topic.body}
</>
);
}
{props.params.id} 이 코드를 통해 id값에 접근할 수 있지만 layout.js는 [id]의 밖에 있기에 props로는 params가 주입되지 않습니다. 그러면 무엇을 써야할까요?
useParams 를 써야합니다. 이는 Client component hook 입니다. 하지만 현재 코드는 Server component임을 확인할 수 있습니다. 즉, 사용할 수 없다는 것인데 어떻게 layout.js에서 useParams를 사용할 수 있을까요?
그 전에
useParams 는 어떤 함수일까요?
useParams:리액트에서 라우터 사용 시 파라미터 정보를 가져와 활용하고 싶다면 useParams라는 훅을 사용하면 된다.
//Control.js
function Control() {
return (
<ul>
<li>
<Link href="/create">Create</Link>
</li>
<li>
<Link href="/update/1">Update</Link>
</li>
<li>
<input type="button" value="delete" />
</li>
</ul>
);
}
하지만 특정 함수만 다른 타입의 컴포넌트로 바꿀 수 없기 때문에 별도의 파일로 쪼개겠습니다.
”use client”; 추가합니다.const params=useParams(); 를 추가하여 파라미터 정보를 가져와 변수 params 에 저장합니다.//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>
);
}