20220110のReactに関する記事は9件です。

プラグアブルなNext.jsのディレクトリ構成

仕様や要件の変更が多発する環境で Next.js を利用したフロントエンド開発をしていて、こういった構成が良いのではないか?と言うのが段々見えてきたので、一旦雑に公開してみます 前提条件 Next.js 12 React 17 Jest 27 Function Component TypeScript 参考構成 基本的な思想 開発が予測不能であることはもはや当たり前だと感じているので、予測しないことこそが開発の肝かなとは思っています そのために個人的に重視しているのは次の点です 何も考えない 仕様変更が多発している環境で毎回考えていては到底時間が足りません 考えなければいけないということは、複雑性が眠っていると考えています 何事も単純にしていきたい、単純であるということは変更が容易であるはず 着脱が容易なコンポーネント構成 いわゆるプラグイン的な構成です 昔プラグインを増やすことで何でも出来るようになるソフトとかあったと思いますが、そういうノリです 具体的にはページコンポーネントを基底コンポーネントとし、その上に乗せるコンポーネントを全てプラグインとして考える方法です 仕様変更が起きてもプラグインをすり替えるだけで極力対応できるようにするというのが目標です 影響を受けた思想 Atomic Design コンポーネントの分割レベルについて参考にしています MUI コンポーネントの分割名称について参考にしています MVC UI、ロジック、データの分離について参考にしています MVVM 画面を扱う上で、どうしても View と Model が結合する場面があり、排除できない要素です SOLID 単一責任の原則:実装のスパゲティ化を防ぐ上では非常に大切です 開放/閉鎖原則:カプセル化として解釈してます 各コンポーネントや関数は実装の詳細を知らずとも使えるべきで、実装の詳細が変わったところでインターフェースが不変であれば問題ないと考えます リスコフの置換原則:シラネ インターフェース分離の原則:取り敢えず用途別に型を用意しとけば丸いかなという認識、型まみれになりますが… 依存性逆転の原則:これもカプセル化かなぁという感じ 基本的に親を具象、子は抽象として考えておけば変更に強くなるかなとは思います そうしておけば少なくとも親が子に引きずられることがなくなるので(理想的には) KISS 何事も単純であることが理解しやすいです 物事を複雑に捉えてしまい、実装が複雑化してしまうことはよくあると思いますが、過度に複雑なコードは変更が困難になります DRY 同じことを二度書かないということですが、同じコードを二度書かないという意味で捉えると危なくなります OOP 関数指向だから OOP が要らないかと言うとそんなことはないです リスペクトできる部分はリスペクトするべき FP いわゆるクラスを使わないので ディレクトリツリー 基本的には Atomic Design を MUI 寄りに解釈したものと、MVC の考えがベースです 若干リポジトリ設定などの開発設定的なものも入ってますが CI を含めて考えているので仕様です ├─.github │ ├─ISSUE_TEMPLATE │ └─workflows ├─.hooks ├─.vscode ├─@types ├─docs │ └─assets ├─public │ └─assets ├─src │ ├─components │ │ ├─cards │ │ │ └─specs │ │ ├─commons │ │ │ └─specs │ │ ├─displays │ │ │ └─specs │ │ ├─forms │ │ │ ├─commons │ │ │ │ └─specs │ │ │ └─specifiedes │ │ │ └─specs │ │ ├─layouts │ │ │ └─specs │ │ ├─sections │ │ │ └─specs │ │ └─templates │ │ └─specs │ ├─contexts │ ├─controllers │ │ └─specs │ ├─hooks │ │ ├─effective │ │ │ └─specs │ │ └─state │ │ ├─commons │ │ │ └─specs │ │ ├─specifiedes │ │ │ └─specs │ │ └─pages │ │ └─specs │ ├─pages │ │ └─specs │ ├─resources │ │ └─specs │ ├─routes │ ├─types │ │ ├─responses │ │ └─specs │ ├─utils │ │ └─specs │ └─validators │ └─specs └─__mocks__ └─next 各ディレクトリの説明 .github/ GitHub のワークフローとか Issue や PR テンプレート .hooks/ Git Hooks ローカル CI 用です GitHub Actions で利用する CPU 時間の節約用です pre-push で TSC の型チェックと ESLint の構文チェックを行った上で、自動フォーマットを掛けます このフォーマットで差分が出た場合は git push をコカします post-merge で package-lock.json の更新を検知し npm ci を行います .vscode/ VSCode の設定 デバッグランチャ、共通的な編集・拡張の設定 推奨拡張機能の指定 @types/ window 配下にぶら下げる外部スクリプトの型定義です GTM とか reCAPTCHA とかそういう系 docs/ 次の説明資料、ファイルとしては md と yaml プロジェクトの簡単な概要説明 開発規約 開発環境構築資料 ディレクトリ構成説明 URI ディレクトリ設計 環境別の設定ファイルや package.json の説明資料 docs/assets/ 説明資料で利用してる画像とか public/assets/ Next.js の静的ファイル置き場 他のシステムと競合させないためにルート階層には何も置かない assets/ もユニークな名前にしておくと安泰 src/ ソースコード全般のルート階層 ここには何も置かない UT は各階層の specs/ に配置 必要に応じて __mock__/ をモックデータ置き場として設置 src/components/ 共通コンポーネントのルート階層 ディレクトリの切り方は MUI を少し意識しています ここには何も置かない この階層のコンポーネントには原則として外部に影響するロジックは持たせない 状態やロジックは props 経由で受け渡す src/components/cards/ いわゆるカード・バナー系のコンポーネント 例外なくロジック・state・hooks を持ちません src/components/commons/ 分類できない子達、ゴミ箱とも言う 例外なく state・hooks を持ちません 責務上必要な必要最低限のロジックを持つケースがあります src/components/displays/ 文言表示するだけとか、画像表示するだけとか 例外なく state・hooks を持ちません 責務上必要な必要最低限のロジックを持つケースがあります src/components/forms/commons/ 入力フォーム系の基底部品 例外なく state・hooks を持ちません 責務上必要な必要最低限のロジックを持つケースがあります src/components/forms/specifiedes/ 入力フォーム系の派生部品 年月日入力みたいなコンボされてるやつはココ 例外なく state・hooks を持ちません 責務上必要な必要最低限のロジックを持つケースがあります src/components/layouts/ ページ全体をラップする大枠、<body /> 直下 Next.js の公式 Boilerplate にも入ってる 例外なくロジック・state・hooks を持ちません src/components/sections/ ヘッダーやフッター ページの共通コンテンツ部分など 例外なくロジック・state・hooks を持ちません src/components/templates/ レイアウトコンポーネント直下に来る内容です 例外なくロジック・state・hooks を持ちません src/contexts/ useContext 用の元ネタです URI 階層別に Context を切ります src/controllers/ 画面のロジックです ここにある処理をページコンポーネントから参照し、テンプレートコンポーネントに差し込む使い方をします これによって UI の共通化は各ページコンポーネントからテンプレートコンポーネントを読み込み、コントローラー関数を注入することでロジックの共通化を実現します ページ単位で特殊な仕様が来た場合は差し込む処理をすり替えるだけなので仕様変更に対して強くなります テンプレートコンポーネントが大きすぎる場合は各ページコンポーネント側で個々にセクションコンポーネントを組み立てるなど、柔軟な運用ができるように設計します 関数の export は以下のようにオブジェクトとしてやります(Autoimport がだるいことになるので…) const foo = (val: string) => { return `++ ${val} ++`; } /** 云々 */ export const FooController = { /** かんぬん */ foo, }; src/hooks/ 共通的な Hook や画面単位の Hook ルート階層 src/hooks/effective/ 副作用付きの Hook です useState + (useRouter | useEffect) など、状態と副作用系が密結合した仕様に対処する為の物です 予期せぬ振る舞いをするものが多いので分けています src/hooks/state/ いわゆる Custom Hook のルート階層 useState の塊です src/hooks/state/common/ 汎用の共通状態です src/hooks/state/specifiedes/ 汎用の共通状態を継承しているものです src/hooks/state/pages/ ページ向けのものです ページコンポーネントに書くと長くなりすぎるので外出し src/pages/ ページコンポーネント UT を書くためにファイル名は細工する <page-name>.page.tsx 雰囲気はこんな感じ const FooPage = () => { const ps = useFooPageState(); const onSubmit = () => { FooController.requestPiyo(ps.hoge.value, ps.hoge.setError); } <FooLayout title={AppRoute.foo.title}> <BarTemplate hoge={ps.hoge} onSubmit={onSubmit} /> </FooLayout> } export default FooPage; src/resources/ 固定文言や API との疎通用の定数とか、そこら辺 src/routes/ ルーティングの定義です ページパスやタイトルなどのメタ情報を定義しています router.push() のパスの共通化が主目的 物理パスが変わった場合はこちらも変える必要があります(二重管理) src/types/ 型定義のルート階層です 循環参照や、型の依存を下げる目的で共通的な型はココに集約しています 責務範囲が限られる Hook や API リクエストの型はそちら側に持たせています src/types/responses/ JSON API の型を定義しています 要するに JSON 色付け職人フォルダです src/utils/ 分類できない共通処理置き場 ページコンポーネントを除く各コンポーネント向けの注入処理が多めです テスト用のユーティリティもココ 関数の export は以下のようにオブジェクトとしてやります(Autoimport がだるいことになるので…) const foo = (val: string) => { return `++ ${val} ++`; } /** 云々 */ export const FooUtil = { /** かんぬん */ foo, }; src/validators/ 共通的なバリデータです __mocks__/next/ Next.js の基底モックデータ あとがき 規模が大きくなると export がだるくなってくるので、どうしようかなというのが悩み ディレクトリ階層もカオスが進みがち 平置きしているところはファイルが甚大なことに しかし AutoImport の利便性は捨てがたい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python WebフレームワークPlotly Dashで資産管理アプリを作成

Dashとは Dashは、データ可視化インターフェースを構築するためのオープンソースフレームワークです。 2017年にPythonのライブラリとしてリリースされ、RやJuliaの実装を含むまでに成長しました。 Flask、React.js、Plotly.jsの3つの技術を使って作成されています。 2020年にリリースされたStreamlitの人気がとても高くなっていますが、2018年からとても高い人気を誇ってます。 ライブラリをインストール pip install pandas pip install dash タイトルを作成 # -*- coding: utf-8 -*- import dash import dash_html_components as html app = dash.Dash(__name__) app.layout = html.Div(children=[ html.H1(children='資産管理'), ]) if __name__ == '__main__': app.run_server(debug=False, host = '127.0.0.1',port=8000) 実行動画 動画の実装結果
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【React x Typescript】リンク切れの画像の代替画像を表示する

概要 画像がリンク切れの時に表示されるimgコンポーネントってイケてないですよね。 そんな時、画像リンク切れの時は別の画像を表示したいニーズが存在すると思います。 React x Typescriptの組み合わせで微妙にハマってしまったので、整理します。 ※なお、リンク切れ時には、例えば以下のように表示されます。 環境 $ node -v v16.13.1 $ npm -v 8.1.2 実装 ポイントは、currentTarget使用する or onErrorの返り値をany型で明示的に指定してあげることでした。 ※@YutaUraさんのコメントより、対策法を追加しました!ありがとうございます! export const App: React.FC = () => { const imgPath = 'https://pbs.twimg.com/profile_banners/1353986308062908417/1620745196/1080x360' const dummy_img = 'https://pbs.twimg.com/profile_banners/2968069742/1628067771/1500x500' return ( <div className="App"> <img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e) => { e.currentTarget.src = dummy_img }} /> {/* もしくは以下のように記載 */} <img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e: any) => { e.target.src = dummy_img }} /> </div> ) } 解説 Reactのimgコンポーネントは、React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>であり、そのonErrorオプションで返却される値の型は、React.SyntheticEvent<HTMLImageElement, Event>です。 この記事を参考に実装してみましたが、どうやらこの型にはsrcは含まれておらず、下記のようなエラーが表示されました。 {/* こうやって書くのはダメだよ */} <img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e) => {e.target.src}}/> エラー文 Property 'src' does not exist on type 'EventTarget'. 色々試行錯誤した結果、上記のサンプルのように、currentTargetを使用するか、返り値eにany型を付けて実装することで、本エラーを回避できます。 余談 Typescriptなのにany使うとは何事だ!と怒られてしまうかもしれません。。。 いいアイデアあれば、コメントいただけると幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

map関数と三項演算子を組み合わせる方法 with TailwindCSS

背景と実施したこと map関数を使った実装中に「最後の要素だけはこのスタイルを適用したい!」と思ったことはないでしょうか。 この実装に少し苦戦したので、備忘録を残します。 今回やりたかったのは、以下のような実装でmapで各コンテンツを繰り返し表示させるわけですが 区切りのborderは真ん中の2本だけで、右端には表示させたくないのです。 こうなると単純な繰り返し(mapd関数)だけでは実現できないので少し工夫が必要でした。 今回使用している技術の情報は以下の通りです。 next: 12.0.7 react: 17.0.2 TailwindCSS: 3.01 typescript: 4.5.4 【追記】 今回のケースでは「divide」を使うのが一番早いということをご指摘いただきました。 遠回りしたけど、結果としてmapと三項演算子の組み合わせという武器が増えたのでヨシッ! (まだまだCSS勉強しないとだめですね。。。) 目次 概要 mapと三項演算子を組み合わせる lastを使うという選択肢もある まとめ 概要 テンプレートリテラル(バッククォート)を活用することで、三項演算子とmapを組み合わせることができるよ 単純に子要素だけ、ということであれば「last」というCSSがあるのでそれでもいいよ lastだけでは解決できない場合があるからやっぱり、mapと三項演算子の組み合わせは知っておいたほうがいいよ mapと三項演算子を組み合わせる 結論からいうと以下のような記載で実現できました <div className='flex-row justify-between md:flex'> {items.map((item: valueItems, index: number) => ( <div key={index} className='basis-1/3 '> <div className={`pt-2 mx-8 text-center md:border-r-4 md:border-[#c5eaea] ${ items.length - 1 === index ? 'border-none' : '' }`} > <Image src={item.src} alt={item.alt} width={184} height={157}></Image> </div> <h3 id='values' className={`pt-2 mx-8 text-lg font-bold text-center text-secondary-black md:border-r-4 md:border-[#c5eaea] ${ items.length - 1 === index ? 'border-none' : '' }`} > {item.name} </h3> <p className={`px-4 pt-2 mx-8 text-left md:border-r-4 md:border-[#c5eaea] ${ items.length - 1 === index ? 'border-none' : '' }`} > {item.text} </p> </div> ))} </div> classNameを {`px-4 pt-2 mx-8 text-left md:border-r-4 md:border-[#c5eaea] ${items.length - 1 === index ? 'border-none' : ''}`} こんな感じでバッククォーテーションでくくっているのがポイントです。 これはES6から出た「テンプレートリテラル」と呼ばれるもので、${hoge} という記述をするだけで 変数を展開してくれます。 このテンプレートリテラルの中で三項演算子を記述することで、最後の要素の時のCSSを記述できます。 lastを使うという選択肢もある CSSではlast-childやfirst-childという指定の仕方もあり、これを使って最初の要素または最後の要素のCSSを変更することもできます。 ただ、私が少し動かしてみたところ <div className='flex-row justify-between md:flex'> {items.map((item: valueItems, index: number) => ( <div key={index} className='basis-1/3 last:hogehoge'> <div className='pt-2 mx-8 text-center md:border-r-4 md:border-[#c5eaea]'> この指定ちゃんと適用されるのですが <div className='flex-row justify-between md:flex'> {items.map((item: valueItems, index: number) => ( <div key={index} className='basis-1/3'> <div className='pt-2 mx-8 text-center md:border-r-4 md:border-[#c5eaea] last:hogehoge'> この指定では適用されませんでした。(繰り返しの中の最初の要素にしか適用されない??) ここはもし良いやり方をご存じの方がいればコメントをいただきたいです。 ということで、今回の実装ではlastは使わず(使えず)、三項演算子を組み合わせたのでした。 つぶしがきくので、このやり方を知っておいても損はないでしょう。 まとめ 今回は、三項演算子とmapの組み合わせ方をご紹介しました。 以下が本記事のまとめです。 テンプレートリテラルは便利そうですし、もっと活用していきたいですね。 テンプレートリテラル(バッククォート)を活用することで、三項演算子とmapを組み合わせることができるよ 単純に子要素だけ、ということであれば「last」というCSSがあるのでそれでもいいよ lastだけでは解決できない場合があるからやっぱり、mapと三項演算子の組み合わせは知っておいたほうがいいよ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Typescriptでinputフォームの値を取得する

Typescriptの勉強を最近始めたのですが、stringとかarrayとかの変数の型周りは他にも静的型付け言語をやっていたので特に問題なくは入れたものの、イベント周りの型が結構鬼門でタイトル通りの簡単なことをしたいだけなのに割とハマってしまい、ベストプラクティスが分かりませんでした... そんなTypescriptを同じく始めたばかりのどなたかに刺されば幸いです。 App.tsx import { useState, useEffect, useRef, ReactEventHandler } from "react"; type TodoType = { id: number; todo: string; isDone: boolean; }; const App: React.FC = () => { const [text, setText] = useState<string>(""); const [todos, setTodos] = useState<TodoType[]>([]); const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => { setText(e.target.value); }; const handleClick = (): void => { setTodos([ ...todos, { id: todos.length++, todo: text, isDone: false } ]); }; return ( <> <input onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleChange(e)} type="text" /> <button onClick={(): void => handleClick()}>Click me</button> {todos.map((i) => ( <li key={i.id}>{i.todo}</li> ))} </> ); }; export default App; onClickについては別にイベントから値を受け取っているわけではないので特に問題ではないのですが、onChangeについてはevent.target.valueからの値を受け取ってstateに保存したかった場合に、イベント型としてChangeEvent<HTMLInputElement>を渡せばいけるのですが、なぜかこれにたどり着くまでに数時間溶かしました...(とはいえTypescript周りは親切なので、xxの型はoo型に渡せません、というエラーが出ればoo型に修正して渡してやれば良いだけなので大分分かりやすいです。) イベントはReact.イベント型としてやればインポートも必要なく使えます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React Hook Form バリーデーション実装

ReactHookを使ってバリデーション機能実装の復習用記事です。 React Hook Form・・・入力フォームの管理に特化したReact向けのライブラリ https://ja.reactjs.org/docs/uncontrolled-components.html バリデーション 実装コード react.tsx const { register, handleSubmit, formSteate: { errors } } = useForm<Values>(); useFormからメソッドを受け取る register・・・入力または選択された要素を登録 handleSubmit・・・検証が成功するとフォーム内のデータを受け取る formSteate: { errors }・・・バリデーションエラーを受け取る react.tsx <input id="email" name="email" type="text" {...register("email", {required: true, pattern:/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,})}/> inputに入力した内容がregisterに登録された内容で検証される react.tsx <span className="text-red-600"> {errors.email?.type === "required" && "メールアドレスを入力してください"} {errors.email?.type === "pattern" && "正しい形式でメールアドレスを入力してください"} </span> registerでエラーが発生した場合、そのregisterに設定したkeyでerrorから取り出すことができる{error.key} エラーが存在しているかどうかでエラーメッセージを表示する ※typeでどの条件のエラーかを判別 submitを押さなくてもバリデーションが行われる react.tsx const { register, handleSubmit, formSteate: { errors } } = useForm<Values>({mode:"onChange"}); mode:"onChange" ・・・submitを押さなくてもonChangeでバリデーションが実行される
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React+ViteをHerokuにデプロイしようとしたらエラーに悩まされた話

一端のエンジニアらしく自分でサービスを作ってみようとしてHerokuですぐつまづいたのでその備忘録 ディレクトリ構成の罠 herokuのアカウント作成・github連携はすんなりいき、いざ deploy branchボタンを押すとこんなエラーが ERROR: Application not supported by 'heroku/nodejs' buildpack ! ! The 'heroku/nodejs' buildpack is set on this application, but was ! unable to detect a Node.js codebase. ! ! A Node.js app on Heroku requires a 'package.json' at the root of ! the directory structure. package.jsonがルートディレクトリにない...? それもそのはず。herokuと連携していはgithubのブランチではこんな構成を取っていた。 ├── backend │ ├── api │ ├── backend │ └── manage.py ├── frontend │ ├── src │ ├── index.html │ ├── package.json │ ├── ... │ ├── docker-compose.yaml ├── DockerfileDjango ├── DockerfileNode ├── ... 要はReactのコードをfrontendディレクトリの配下においていたせいでherokuがpackage.jsonを見つけれなかったというエラーだった。package.jsonがfrontendの下にいると教えるのが一番なのだけど、やり方がわからず断念。諦めてfrontend以下のコードを全部移動させてこんな感じに。 ├── backend │ ├── api │ ├── backend │ └── manage.py ├── src ├── index.html ├── package.json ├── ... ├── docker-compose.yaml ├── DockerfileDjango ├── DockerfileNode ├── ... これでデプロイは通った。 Application Error デプロイが終わって早速URLを叩いてみるとこんな画面が ログを確認するとcode=H14やらcode=H10のエラーが。 これはルートディレクトリにProcfileなるものを作ったり、package.jsonをいじったり、npmでライブラリを追加したら直った。 npm i serve Procfile web: npm start package.json "scripts": { "dev": "vite", "heroku-postbuild": "npm run build", "start": "serve -s build", "build": "tsc && vite build", "serve": "vite preview" } 404 page not found 何度もデプロイを試していると突然の404。 エラーは直ったっぽいけど今度は404。今回の原因はViteにありそう。おそらくViteでbuildしたディレクトリを見つけれてないようだ。 Viteの公式ページによるとoutDirでビルド先を変更できるようだ。 vite.config.ts import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ root: process.cwd(), plugins: [react()], build:{//この部分を追加 outDir:"./build" }, server:{ host:'0.0.0.0' } }) 多分rootは書かなくてもいいと思う。デフォルトと同じだし。出力先をbuildディレクトリに設定。デフォルトではdistディレクトリが作られていて、それでherokuがビルド後のファイルを見つけれなくて404になっていたと思われる。 これでやっとこさ herukuのデプロイが完了!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React Router v6 画面遷移先に値を送る

コンポーネント間での値の受け渡しについての記事です。 最初のページ(App.js)でLinkタグの属性stateで送りたい値を設定します。 App.js import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom"; import NextPage from './NextPage'; const App = () => { return ( <Router> <div> <Link to="/next" state={{test: 'test'}}> <h5>NextPage</h5> </Link> <Routes> <Route path="/next" element={<NextPage/>}> </Route> </Routes> </div> </Router> ) } export default App; 画面遷移先のページ(NextPage.js)でuseLocation()でlocationを取得し、更にlocationからstateを取得します。 画面遷移先のページで{"test": "test"}が表示されます。 NextPage.js import React, { useState, useEffect } from "react"; import { useLocation } from "react-router-dom"; const NextPage = () => { const location = useLocation(); return ( <div> {JSON.stringify(location.state)} </div> ) };
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【React】外部APIからデータを取得して表示する方法

はじめに  本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。  そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。  間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。 外部APIからデータを取得して表示する方法 Reactで、外部APIからデータを取得して表示するには、fetch()を使用し、以下のように記述します。 // Hookを使用しない場合 componentDidMount(){ fetch("APIのURL") .then(response => response.json()) .then(data => { this.setState({ character: data, loading: false }) }) .catch(error => { console.error(error) } } // Hookを使用した場合 useEffect(() => { fetch("APIのURL") .then(response => response.json()) .then(data => { this.setState({ character: data, loading: false }) }) .catch(error => { console.error(error) } }, []) fetchメソッドはComponentDidMount内で行います。 fetch(APIのURI):APIを取得する .then(response => response.json()):データ取得完了後、取得したPromise型の値をオブジェクト化 .then(data => …):「…」に必要な処理を記述 .catch(): エラーの場合の処理を記述
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む