🐕
React Foundationsを読んでわからなかったことのメモ
React hooksについて
参考にメモする
Reactにはフックと呼ばれる関数群がある。フックを使えば、ステートのような追加ロジックをコンポーネントに追加できる。ステートとは、時間の経過とともに変化するUIの情報のことで、通常はユーザーとのインタラクションがトリガーになります。
stateを管理する関数として useState
関数がある。
以下のように、配列を返します。
function HomePage() {
// ...
const [likes, setLikes] = React.useState();
// ...
}
1番目の変数は、stateの値を表します。名前は何でも良いです。
2番目の変数は、stateを更新する関数を表します。prefixのset
以外の名前は何でもよいです。
stateの値wの初期値を設定するには次のようにします。
function HomePage() {
// ...
const [likes, setLikes] = React.useState(0);
}
これらを使う例としては以下のようになります。
function HomePage() {
// ...
const [likes, setLikes] = React.useState(0);
function handleClick() {
setLikes(likes + 1);
}
return (
<div>
{/* ... */}
<button onClick={handleClick}>Likes ({likes})</button>
</div>
);
}
next.jsのどこに書けばいいのか?
たとえば上のコードをNext.jsのどこにかけばいいのか最初だとわからないのでメモっておく。
結論から言うと、app/pages.tsx
に書けばいい。
import { useState } from 'react';
function Header({title} : {title:string}) {
return <h1>{title ? title : 'Default title'}</h1>;
}
export default function HomePage() {
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return (
<div>
<Header title="Develop. Preview. Ship." />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
<button onClick={handleClick}>Like ({likes})</button>
</div>
);
}
ただこれだと以下のエラーがでる。
Error:
× You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
│ Learn more: https://nextjs.org/docs/getting-started/react-essentials
Next.jsはデフォルトでServer Componentsを使用します。これはアプリケーションのパフォーマンスを向上させるためで、Server Componentsを採用するために追加の手順を踏む必要はありません。
ブラウザのエラーを見ると、Next.jsは、サーバーコンポーネント内でuseStateを使おうとしていることを警告しています。インタラクティブな「Like」ボタンをクライアント コンポーネントに移動することで、これを修正できます。
LikeButtonコンポーネントをエクスポートする、like-button.jsという新しいファイルをappフォルダ内に作成します。
app/like-button.tsx
'use client';
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>
}
app/page.tsx
import LikeButton from './like-button';
function Header({title} : {title:string}) {
return <h1>{title ? title : 'Default title'}</h1>;
}
export default function HomePage() {
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
return (
<div>
<Header title="Develop. Preview. Ship." />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
<LikeButton />
</div>
);
}
これでエラーなく表示できるようになった。
Discussion