Open28

何もかも初心者がNext.js を始めてからつまづいたところ等のメモ

tsuma_yojitsuma_yoji

VSCode にて prettier でソースコード保存時に自動整形したい

tsuma_yojitsuma_yoji

Windowsなんだけど、Macでとか、json開いて書き足すとか、色々見て試してもまったく動かない。

tsuma_yojitsuma_yoji

プロジェクトフォルダ(create-next-appで作成されたフォルダ)の中に .prettierrc.json を追加するとprettierの整形ルールをカスタマイズできる。
とりあえずシングルクォートにするだけ追記。

{
  "singleQuote": true
}
tsuma_yojitsuma_yoji

TypeScriptでうまくいかなかったメモ

tsuma_yojitsuma_yoji

自作のコンポーネントは大文字で始めないといけない。
x myheader
o Myheader or MyHeader

小文字で始めるとタグとして使おうとしたときに 「プロパティ " myheader " は 型 " JSX.IntrinsicElements " に存在しません。」と怒られる。
まじでまったく意味がわからなかった😂

tsuma_yojitsuma_yoji

基本的にReact.FC や React.VFCは使わなくてよいみたい。
普通のfunctionで定義する。

Chakra UI を使ったコンポーネントの定義のひな型

import { ReactNode } from 'react';
import { Box } from '@chakra-ui/react';

const Header = (props?: ReactNode): JSX.Element => {
  return (
    <Box {...props}>
      hoge
    </Box>
  );
};
export default Header;

https://kray.jp/blog/dont-have-to-use-react-fc-and-react-vfc/

tsuma_yojitsuma_yoji

propsを受け取る関数を書くたびに typescript から型を書けと怒られる。
HTMLのタグが受け取る属性がpropsに入ると思うんだけど、それの型って何?🤔

tsuma_yojitsuma_yoji

英語日本語問わず、サンプルにTypeScriptつけてるのがまったくない。
2時間くらい調べてもまったく進まないからいったん props: any で進める。
慣れてきたらわかることもあるだろう😐

tsuma_yojitsuma_yoji

Chakra ui の中に BoxProps などそれぞれのコンポーネントのPropsが定義されてる。
独自の型を受け取りつつ、その他は子コンポーネントに渡す場合の書き方は以下の通りな模様。

Imageをラップしたコンポーネントの例

import { Image, ImageProps } from "@chakra-ui/react";

type Props = {
  src: string;
  alt: string;
  w: string;
  h: string;
} & ImageProps;

const MyImage = ({ src, alt, w, h, ...others }: Props): JSX.Element => {
  return <Image src={src} width={w} height={h} alt={alt} {...others} />;
};
export default MyImage;

tsuma_yojitsuma_yoji

src フォルダを作ってそこに色々まとめたい

tsuma_yojitsuma_yoji

とりあえずこんな感じ

ProjectFolder
├.next
├node_modules
├public
│ └images
├src
│ ├components
│ └pages
├package.json
├.prettierrc.json
├tsconfig.json

tsuma_yojitsuma_yoji

tsconfig.json の "compilerOptions" に以下を追記

  "compilerOptions": {
    ...
    "baseUrl": "src",
    "paths": {
      "~/components/*": ["components/*"],
      "~/images/*": ["../public/images/*"]
    }

これでどの階層からでも "~/components/***" って感じで
絶対パスのようにアクセスできるようになる。らしい。

tsuma_yojitsuma_yoji

いろいろ追加した。

  "compilerOptions": {
    ...
    "baseUrl": ".",
    "paths": {
      "@comp/*": ["src/components/*"],
      "@lib/*": ["src/lib/*"],
      "@data/*": ["src/data/*"]
    }

使い方

import MyLink from "@comp/MyLink";
import MyImage from "@comp/MyImage";

ちなみにtsconfig.jsonとか更新した時はデバッグ用のローカルホスト(?yarn devしてるやつ)を一回再起動しないと適用されないらしい。
importしてるやつが見つからないって実行時エラーが出て全然わけがわからなかった🤣

tsuma_yojitsuma_yoji

yarn create-next-app をして生成されたフォルダに移動して yarn dev をするとめちゃくちゃたくさん下記のエラーが出る。

There are multiple modules with names that only differ in casing.

どうやらパスの大文字と小文字の指定を間違えたりしてると出るらしい。
初期生成の段階でそこ躓かれると困る🤣
とりあえず、Documents\vscode\NextProject\ でダメだったので
Documents\p\nextproject で yarn create-next-app したらうまくいった。

…何が何だか わからない…
色々やり直したりしてフォルダ削除とかしまくってたのが影響しているんだろうか😂

tsuma_yojitsuma_yoji

<Link>タグを使ってページ遷移する際に絶対パスで指定する方法がわからない。
ルートフォルダにある index.tsx に戻りたいけど
/items/item1.tsx から戻るパスの指定方法がわからない。

tsuma_yojitsuma_yoji

<Link href="/"></Link> で絶対パスとしてルートフォルダのindex.tsxに戻れる。
<Link href="."></Link> は現在の階層を指す。

tsuma_yojitsuma_yoji

SSGでサイトを作りたいけど画像最適化は利用したい場合にどうすればいいか調べる。

tsuma_yojitsuma_yoji

そういうサービスがいろいろあるらしい。
GraphCMSが個人利用では使いやすそうなイメージ?

tsuma_yojitsuma_yoji

ただ画像読み込み先を書き換えないといけないぽい?
ローカル+オフラインで基本書いてるからデバッグができなくなりそう(q,q)

tsuma_yojitsuma_yoji

とりあえずオフライン時はChakra UI の Image、本チャンでは next/image に切り替えられるよう、MyImage というラッパーコンポーネント(?)を作成した。

//import Image, { ImageProps } from "next/image";
import { Image, ImageProps } from "@chakra-ui/react";

type Props = {
  src: string;
  alt: string;
  w: string;
  h: string;
} & ImageProps;

const MyImage = ({ src, alt, w, h, ...others }: Props): JSX.Element => {
  return <Image src={src} width={w} height={h} alt={alt} {...others} />;
};
export default MyImage;

GraphCMS等を利用した場合、srcのアドレスがどうなるのか、変換できるのかはまた今度。

tsuma_yojitsuma_yoji

テキストの色をサイト上で統一したいので、Chakra UI の色を上書きしたい。

tsuma_yojitsuma_yoji

styles フォルダに Theme.tsx というのを用意して
そこで拡張テーマ上書き

import { extendTheme } from "@chakra-ui/react";

const bgColor = "#ffffff";
const headingColor = "#333333";
const textColor = "#666666";

export const theme = extendTheme({
  styles: {
    global: {
      body: {
        backgroundColor: bgColor,
        color: textColor,
      },
    },
  },
  components: {
    Heading: {
      baseStyle: {
        color: headingColor,
      },
    },
    Button: {
      baseStyle: {
        color: headingColor,
      },
    },
  },
});

_app.tsxで読み込んで <ChakraProvider>タグに読み込むとうまく適用された。

import { AppProps } from "next/app";
import { ChakraProvider } from "@chakra-ui/react";
import { theme } from "../styles/Theme";

function MyApp({ Component, pageProps }: AppProps): JSX.Element {
  return (
    <ChakraProvider theme={theme}>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}

export default MyApp;