20210427のReactに関する記事は11件です。

MockedProviderでApollo Clientを使ったコンポーネントのテスト

はじめに GraphQLの通信部分にApollo Clientを使っている場合、ApolloProviderの代わりにApolloの提供しているMockedProviderを使うことで、GraphQLサーバーに通信をすることなくReactコンポーネントのテストが可能です。 コンポーネントの例 IDを指定してユーザーを取得し、簡単なテキストを表示するコンポーネントです。 import React from 'react'; import { gql, useQuery } from '@apollo/client'; export const GET_USER_QUERY = gql` query GetUser($id: ID) { user(id: $id) { id name age } } `; export function User({ id }) { const { loading, error, data } = useQuery( GET_USER_QUERY, { variables: { id } } ); if (loading) return <p>Loading...</p>; if (error) return <p>An error occurred.</p>; return ( <p> {data.user.name} is {data.user.age} years old. </p> ); } それではテストを追加していきます。 1. レスポンスのモックを定義 request と response フィールドを持つオブジェクトの配列でoperationごとのレスポンスを定義します。 const mocks = [ { request: { query: GET_USER_QUERY, variables: { id: 1, }, }, result: { data: { user: { id: 1, name: 'Tom', age: 25 }, }, }, }, ]; 関数でオブジェクトを返却することも可能 result: () => { // ...何かしらのロジック... return { data: { user: { id: 1, name: 'Tom', age: 25 }, }, } }, 2. 初期のloading状態のテスト イベントループを待つことなく、すぐにそのままテストを実行すると初期のローディング状態でコンポーネントがレンダリングされます。 import TestRenderer from 'react-test-renderer'; import { MockedProvider } from '@apollo/client/testing'; ... it('renders without error', () => { const component = TestRenderer.create( <MockedProvider mocks={mocks} addTypename={false}> <User id={1} /> </MockedProvider>, ); const tree = component.toJSON(); expect(tree.children).toContain('Loading...'); }); リクエスト時、本来は__typenameフィールドがクエリに含まれるのですが、テストの際はaddTypenameをfalseにすることでモックのリクエストとレスポンスに__typenameフィールドを含める必要がなくなります。 3. success状態のテスト setTimeoutしてMockedProviderがモックのレスポンスを取得する処理を走らせます it('should render user', async () => { const component = TestRenderer.create( <MockedProvider mocks={mocks} addTypename={false}> <User id={1} /> </MockedProvider>, ); // レスポンスを取得 await new Promise(resolve => setTimeout(resolve, 0)); const p = component.root.findByType('p'); expect(p.children.join('')).toContain('Tom is 25 years old.'); }); 4. error状態のテスト モックにエラーのレスポンスを定義 const mocks = [ { request: { query: GET_USER_QUERY, variables: { id: 1, }, }, error: new Error('An error occurred.'), }, ]; successの時と同様にモックのレスポンスを取得 it('should render error message', async () => { const component = TestRenderer.create( <MockedProvider mocks={mocks} addTypename={false}> <User id={1} /> </MockedProvider>, ); // レスポンスを取得 await new Promise(resolve => setTimeout(resolve, 0)); const tree = component.toJSON(); expect(tree.children).toContain('An error occurred'); }); Mutationのテスト ユーザーを削除するボタンのコンポーネントです。 export const DELETE_USER_MUTATION = gql` mutation deleteUser($id: ID!) { deleteUser(id: $id) { id name age } } `; export function DeleteButton() { const [mutate, { loading, error, data }] = useMutation(DELETE_USER_MUTATION); if (loading) return <p>Loading...</p>; if (error) return <p>An error occurred.</p>; if (data) return <p>Deleted.</p>; return ( <button onClick={() => mutate({ variables: { id: 1 } })}> Click to Delete Tom </button> ); } まずはクエリの際と同様にモックのレスポンスを定義 const mocks = [ { request: { query: DELETE_USER_MUTATION, variables: { id: 1, }, }, result: { data: { deleteUser: { id: 1, name: 'Tom', age: 25 }, }, }, }, ]; onClick をトリガーしてMutationを実行 it('should delete user', async () => { const component = TestRenderer.create( <MockedProvider mocks={mocks} addTypename={false}> <DeleteButton /> </MockedProvider>, ); // ボタンをクリック const button = component.root.findByType('button'); button.props.onClick(); // レスポンスを取得 await new Promise(resolve => setTimeout(resolve, 0)); const tree = component.toJSON(); expect(tree.children).toContain('Deleted!'); }); まとめ 今回はGraphQLサーバーに通信をすることなくReactコンポーネントのテストができるMockedProviderのご紹介でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Module not found: Can't resolve "history/createBrowserHistory"

React入門で学習時に詰まったエラー historyがないよと10時間ほど怒られ続けた後に、神のごとき記事に出会いました。 しかもその後すぐに閉鎖してしまった様。リニューアルするとの事なので心から待ち続けます。 記事によると どうもv5では機能しないようでhistoryをv4にダウングレードせよとの事。 (って解釈で合ってるんだよな?英語だったからようわからん) npm install --save history@4.10.1 もしくは npm install --save history@4.9.0 そしたら次はこんなエラー Could not find router reducer in state tree, it must be mounted under "router" そもそもreact-router-redux自体が推奨されていない様なので こちらに関してはconnected-react-routerをインストールして 下記の記事を参考に書き換え。 本の内容とは変わってしまったがようやくエラー解消と。 Reactはバージョン違いによる不具合が多く、初級者を悩ませるようで 技術書使うならそのへんを明記してるものを選んだ方が良いのかと思いました。 バージョンを意識した開発は未だ未経験だったので良い勉強になってよかったです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React-Leafletでマップを表示

はじめに React で地図を表示させ、その上にマーカーを表示させる。React Leaflet を参考に進めた。React の基本的な知識は知っている前提とする。 React-Leaflet のインストール 以下コマンドで、インストールできる。 $ npm install react react-dom leaflet $ npm install react-leaflet leaflet コンポーネントの作成 指定座標を中心に地図を表示させ、さらにマーカーを配置するコンポーネントを作成する。任意のディレクトリで SimpleLeaflet.js というファイルを作成し、以下コードを書く。ここでは components/Leaflet ディレクトリの直下に置いた。useState を使うことで指定位置やズームを変更することを見据えて position や zoom を作成しているが、この記事ではとくに用いていない。 SimpleLeaflet.js import React, { useState } from "react"; import "leaflet/dist/leaflet.css"; import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet"; const SimpleLeaflet = () => { const [position, setPosition] = useState({ lat: 51.505, lng: -0.09, }); const [zoom, setZoom] = useState(13); return ( <div> <MapContainer center={position} zoom={zoom} style={{ height: "50vh" }}> <TileLayer attribution='&amp;copy <a href="http://osm.org/copyright";>OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <Marker position={position}> <Popup> A pretty CSS3 popup. <br /> Easily customizable. </Popup> </Marker> </MapContainer> </div> ); }; export default SimpleLeaflet; 上記コンポーネントを作成後、App.js などに import SimpleLeaflet from "components/Leaflet/SimpleLeaflet.js"; でコンポーネントを読み込み、出力したい場所で <SimpleLeaflet /> とすれば以下のように地図を表示することができる。 import "leaflet/dist/leaflet.css"; での CSS を読み込みや、<MapContainer ... style={{ height: "50vh" }}> で高さの指定をしない場合は地図が適切に表示されないので注意。 上記ではマーカーがまだ表示されていない。調べたところ、Marker not appearing for simple example #453 を発見。これを参考にコードを追記したところ、マーカーを表示できた。 SimpleLeaflet.js import React, { useState } from "react"; import "leaflet/dist/leaflet.css"; import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet"; // add icons import Leaflet from "leaflet"; import icon from "leaflet/dist/images/marker-icon.png"; import iconShadow from "leaflet/dist/images/marker-shadow.png"; // marker setting let DefaultIcon = Leaflet.icon({ iconUrl: icon, shadowUrl: iconShadow, }); Leaflet.Marker.prototype.options.icon = DefaultIcon; const SimpleLeaflet = () => { const [lat, setLat] = useState(51.505); const [lng, setLng] = useState(-0.09); const [zoom, setZoom] = useState(13); const [position, setPosition] = useState({ lat: 51.505, lng: -0.09, }); return ( <div> <MapContainer center={position} zoom={zoom} style={{ height: "50vh" }}> <TileLayer attribution='&amp;copy <a href="http://osm.org/copyright";>OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <Marker position={position}> <Popup> A pretty CSS3 popup. <br /> Easily customizable. </Popup> </Marker> </MapContainer> </div> ); }; export default SimpleLeaflet; クリックすると、ポップアップが表示されることも確認できる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Reactで作ったWebアプリにVueで作ったWebアプリを合体させたい

みなさん、Reactで作ったWebアプリから、React Routerを使ってVueで作ったWebアプリに飛びたいな〜と思ったことないでしょうか!まさに、今回わたくしこのような状況になり、何も考えずにいろんな言語に手を出すんじゃなかったなと少し後悔したのですが、どうしてもReactで実装し直すのが嫌だったので、考えました。 Reactで作ったWebアプリケーションに、Vueで作ったWebアプリケーションを合体する方法の備忘録です。 やりたいこと Reactで実装した左側のアプリとVueで実装した右側のアプリを 合体させたい! 方法検討 調べてみると、iframeを使えば、Webページに他のWebページを埋め込めることがわかりました。 また、ReactにはReact Iframeというのがあったので、これを使ってみました! やってみる 埋め込み作業としては、Reactでの設定だけでできます。Reactのプロジェクトを開いて、React Iframeのインストールから行います。 React Iframeのインストール $ yarn add react-iframe 実装 import React from 'react'; import Iframe from 'react-iframe' export default function Page1(){ return ( <div> <Iframe id = "page1" url = "<埋め込みたいサイトURL>" position="absolute" width="80%" height="90%"/> </div> ); } 必須属性としては、urlのみです。ここに埋め込みたいページのURLを指定します。 そして、このままだと埋め込んだVueのアプリに枠線ができるので、CSSで消しました。 Iframe { border:none; } 完成画面 完成です!簡単に埋め込むことができました! あとはS3にアップロードして、公開することができました。 これで、左側のメニューからこのVueページに飛ぶと、まさかVueで実装しているとは気づかないくらいナチュラルにVueのページを開くことができました! セキュリティについて 最後に、今回iframeについて調べていく中で、セキュリティ面でリスクもあることがわかりましたので、リスクと解決方法についてもまとめておきます。 外部のサイトを埋め込む場合 埋め込んだ外部のサイトに、悪意のある処理が含まれていた場合、システムやユーザーに危害が加わる可能性があります。 それを回避するために、iframeにはsandbox属性という属性が用意されており、外部のサイトが実行することに対して制限をかけることができます。つまり、sandbox属性を使うことで、システムが不正に操作されるのを防ぐことができます。 もちろんReact iframeにもsandbox属性はあります。 自分のサイトが悪用されないように 少し今回の趣旨とは異なりますが、自作のWebサイトがiframeを使って悪意のあるサイトに埋め込まれないようにする方法です。 クリックジャッキングについて調べるとその仕組みについてはたくさん出てきますが、簡単に説明すると、悪意のあるサイト①にサイト②を透過させることで、ユーザーはサイト②を操作していると思っていたら、実は、悪意のあるサイト①を操作していたというような攻撃手法です。 Webサイトの開発側はユーザーがこのような被害に合わないようにするために、対策を行う必要があります。 その対策の一つとして、X-Frame-Optionsをレスポンスヘッダーにつける方法があります。このヘッダーをつけることによって、他ドメインからiframeで埋め込まれないようにすることができます。 今回はS3を静的Webサイトホスティングとして使いましたが、S3のみではこのヘッダーをつけることができません。なので、S3 + CloudFront + Lambda@Edgeを使って構築する必要があります。 おわりに 今回はどうしてもReactのプロジェクトとVueのプロジェクトを合体させたく、React Iframeというのを使ってみました!こんなにも簡単に埋め込むことができました!Vueで作っているものを、Reactで作り直すという話がでていたのですが、回避できてひとまずよかったです。 ReactからVueに値を渡すのに少し苦労したので、次回はそれについてまとめようかなと思っています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React学習アウトプット#1

前置き MDNのReactチュートリアルのようなものがあったので、読んで&&やってみて学んだことのアウトプット記事です。本記事では基礎的なことからpropsまでのことを書いて復習しています。 MDN React入門 環境構築は下記記事を参考にしました。 https://qiita.com/2754github/items/413bdaaa90834e219dc8 何か間違いがあれば指摘していただけると大変励みになります。拙い内容ですがよろしくお願いいたします。 Reactプロジェクトの主なディレクトリ src...主にいじるファイルが入っている public...ブラウザによって読み込まれるファイルが含まれる。Reactはこの中のindex.htmlにコードを挿入する。 初期状態のブラウザ描画の流れ App.js→index.js→index.html App.js 1. App.js内でfunction又はclassを定義する※(前者と後者で状態管理などが変わってくるらしい…) 2. 1で定義したものの中で、retur()内にJSXを記述 3. 「export default 〇〇」で出力 ※ここでは「function App」と定義した index.js 1. App.jsで定義したものをimport 2. render()メソッド内でindex.html内の対象のidを取得して描画 チュートリアル開始 props props …propertiesの略、コンポーネント間でデータを渡すことができる。親から子にのみ渡すことができる。 index.js内のAppコンポーネントを呼び出しているところに下記の様な形で変数に値を代入する。 index.js ReactDOM.render(<App subject="Clarice" />, document.getElementById('root')); 子コンポーネントであるApp.jsで下記のように記述するとデータを渡すことができる App.js function App(props) { console.log(props); return ( // return statement ); } 終わりに 次からはtodoアプリをチュートリアルに沿って作っていこうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MDN Reactチュートリアル復習#1

前置き MDNのReactチュートリアルを読んで&&やってみて学んだことの復習です。本記事では基礎的なことからpropsまでのことを復習しています。 MDN React入門 環境構築は下記記事を参考にしました。 https://qiita.com/2754github/items/413bdaaa90834e219dc8 何か間違いがあれば指摘していただけると大変励みになります。 Reactプロジェクトの主なディレクトリ src...主にいじるファイルが入っている public...ブラウザによって読み込まれるファイルが含まれる。Reactはこの中のindex.htmlにコードを挿入する。 初期状態のブラウザ描画の流れ App.js→index.js→index.html App.js 1. App.js内でfunction又はclassを定義する※(前者と後者で状態管理などが変わってくるらしい…) 2. 1で定義したものの中で、retur()内にJSXを記述 3. 「export default 〇〇」で出力 ※ここでは「function App」と定義した index.js 1. App.jsで定義したものをimport 2. render()メソッド内でindex.html内の対象のidを取得して描画 チュートリアル開始 props props …propertiesの略、コンポーネント間でデータを渡すことができる。親から子にのみ渡すことができる。 index.js内のAppコンポーネントを呼び出しているところに下記の様な形で変数に値を代入する。 index.js ReactDOM.render(<App subject="Clarice" />, document.getElementById('root')); 子コンポーネントであるApp.jsで下記のように記述するとデータを渡すことができる App.js function App(props) { console.log(props); return ( // return statement ); } 終わりに 次からはtodoアプリをチュートリアルに沿って作っていこうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

はてぶで「Wasp」というのを見つけたのでサイトを見たら5分でお試しできるということなので試してみた

はじめに タイトルで記事を書いたきっかけ全部書いた Waspについて サイトに書いてる説明をそのまま引用 A simple language for developing full-stack web apps with less code. Describe high-level features with Wasp DSL and write the rest of your logic in React, Node.js and Prisma. ■ DeepL翻訳 より少ないコードでフルスタックのWebアプリを開発するためのシンプルな言語です。 ハイレベルな機能はWasp DSLで記述し、残りのロジックはReact、Node.js、Prismaで記述します。 なお、Y Combinator1がバックアップしており、Product Hunt2のデイリーランキングで1位をとったこともあります。 お試しする それでは早速お試しする 環境や前提条件 macOS Big Sur バージョン 11.2.3 MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports) プロセッサ 2.4 GHz クアッドコアIntel Core i5 メモリ 16 GB 2133 MHz LPDDR3 試してみる サイトに書かれてる「Try Wasp in 5 minutes →」の通りにまずは実行してみる。 1. Open your terminal and run: $ curl -sSL http://get.wasp-lang.dev | sh 実行結果した結果の中に以下のメッセージがあったのでPATH設定する必要ありそう。。。 ・・・ Wasp has been successfully installed! To create your first app, do: - Add wasp to your PATH as described above. - wasp new MyApp 2. Create a new project: $ wasp new MyFirstApp を実行したら案の定、PATH通ってなくて $ wasp new MyFirstApp zsh: command not found: wasp と実行できなかったのでパスを通してから再度 $ wasp new MyFirstApp Created new Wasp app in ./MyFirstApp directory! To run it, do: cd MyFirstApp wasp start NOTE: Wasp is still in Alpha, therefore not yet production ready and might change significantly in the future versions. 3. Run your first app: $ cd MyFirstApp && wasp start 実行すると、 とブラウザの権限要求してきたので「OK」をクリック。 しばらく待っていたら勝手にブラウザ開いて以下の画面表示されました。 まとめ 本当に5分でできた もう少し詳しい話知りたい人は公式ドキュメントチェックGetting Started | Wasp product huntでデイリー1位をとったのは、2020年12月6日なのでもっと早めにキャッチアップできたら良いなと思いました。 Appendix 参考サイト Wasp | Wasp Y Combinator Wasp-lang Alpha - Develop web apps in React & Nodejs with no boilerplate | Product Hunt ご意見・ご感想をお待ちしております 今回の記事はいかがでしたか? ・こういう記事が読みたい ・こういうところが良かった ・こうした方が良いのではないか などなど、率直なご意見を募集しております。 頂いたお声は、今後の記事の質向上に役立たせて頂きますので、お気軽に コメント欄にてご投稿ください。Twitterでもご意見を受け付けております。 皆様のメッセージをお待ちしております。 スタートアップに投資している会社。有名どころだと「Dropbox」「Airbnb」など。 ↩ プロダクト投稿サイトで、投票によってランキングがでるサイト。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[React Testing Library] debugコマンドで出力が途切れる場合の対処方法

Reactのテストファイルに以下関数を埋め込んで、出力をデバックするケースがあると思います。 // コンポーネントのレンダーを確認 debug() しかしレンダー結果の行数が長い場合、以下のように3点ドットで、全て出力されないケースがあります。 この場合、以下のように出力サイズを上げて確認できます。 DEBUG_PRINT_LIMIT=10000 npm test 参照リンク: Debugging
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[JEST + React Testing Library] debugコマンドで出力が途切れる場合の対処方法

Reactのテストファイルに以下関数を埋め込んで、出力をデバックするケースがあると思います。 // コンポーネントのレンダーを確認 debug() しかしレンダー結果の行数が長い場合、以下のように3点ドットで、全て出力されないケースがあります。 この場合、以下のように出力サイズを上げて確認できます。 DEBUG_PRINT_LIMIT=10000 npm test 参照リンク: Debugging
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JSONファイルを活用してみる

はじめに 初心者の方たちはこれまでにJSONのファイルを読み込んだりする事はあっても、自分でファイルを作成した事がない人も多いのではないでしょうか? まさに私がその人間でした。 アプリを作っていると必ず親コンポートから子コンポーネントに情報を渡す為に、propsを渡す記述をしていくことになると思います。そこで初めてJSONファイルを活用してみました。 これから作るもの まずは作ろうと思っている完成版を先に見てみましょう。 今回の目的はJSONファイルの活用なので、デザインのショボさには目を瞑ってください。 映画詳細の参照サイト 例えばこのように映画の情報を表す3枚のカードがあります。中身の情報が違うだけで、カードの構成は全く同じです。そこで1枚だけのカードをコンポーネント化し、それぞれに映画の「名前、制作年、詳細」の3つ情報を持たせます。 子コンポーネントでは、それぞれを {title},{year},{description}などの適当な名前でpropsとして受け取り表示できるようにしておきます。 ではpropsを渡す親コンポーネントを見てみましょう。 最初に私が書いたコードがこちらです。 /CardComponent.tsx import React from 'react'; import styles from './CardComponent.module.scss'; import CardItem from './CardItem'; const CardComponent: React.VFC = () => { return ( <div className={styles.card_component_wrapper}> <div> <CardItem title="スタンドバイミー" year="1986" description="1986年制作のアメリカ映画。1950年代末のオレゴン州の小さな町キャッスルロックを舞台に、それぞれ心に傷を持った4人の少年たちが好奇心から、線路づたいに“死体探し”の旅に出るという、ひと夏の冒険を描く。" /> </div> <div> <CardItem title="マスク" year="1994" description="1994年のアメリカ映画。主演のジム・キャリーとヒロインのキャメロン・ディアスを一躍トップスターに仕立てた作品。地味な男が不思議な緑色の仮面を手に入れたことから、超人的な力を持った怪人・マスクに大変身する物語である。" /> </div> <div> <CardItem title="タイタニック" year="1997" description="2200人もの乗客と乗員を乗せたまま沈没した大型豪華客船タイタニック号の海難事故をベースに、上流階級の娘と貧しい青年の悲恋を描く感動のスペクタクル。 アカデミー作品賞、監督賞をはじめ11部門を受賞するという快挙を達成した。" /> </div> </div> ); }; 問題点 コードを書いていて初心者ながら不便さを感じておりました。 それは、渡すpropsの詳細が長すぎることです。 今回は渡す情報がたったの3つなのでこのままでも乗り切れますが、もっとpropsの数が多くて渡したい情報がたくさんある場合や、情報の文字数が長すぎる場合は、親コンポーネントの中身がごちゃごちゃして見づらくなります。 基本的な考え方として、常にファイルの中はスッキリと整理しておきたい。 そして親コンポーネントはだたアプリの構造だけを書いているファイルなので、実際に表示したい映画の詳細のデータまで記述したくはありません。そこでファイルを分けることにしました。 JSONファイルの活用 JSONファイルの事をまだ全く分からない方は先にこちらを参考にしてください。 非エンジニアのためのJSON入門 /ItemDescription.json [ { "title": "スタンドバイミー", "year": 1986, "description": "1986年制作のアメリカ映画。1950年代末のオレゴン州の小さな町キャッスルロックを舞台に、それぞれ心に傷を持った4人の少年たちが好奇心から、線路づたいに“死体探し”の旅に出るという、ひと夏の冒険を描く。" }, { "title": "マスク", "year": 1994, "description": "1994年のアメリカ映画。主演のジム・キャリーとヒロインのキャメロン・ディアスを一躍トップスターに仕立てた作品。地味な男が不思議な緑色の仮面を手に入れたことから、超人的な力を持った怪人・マスクに大変身する物語である。" }, { "title": "タイタニック", "year": 1997, "description": "2200人もの乗客と乗員を乗せたまま沈没した大型豪華客船タイタニック号の海難事故をベースに、上流階級の娘と貧しい青年の悲恋を描く感動のスペクタクル。 アカデミー作品賞、監督賞をはじめ11部門を受賞するという快挙を達成した。" } ] まずは新たに拡張子.jsonでJSONファイルを作成します。そしてそのファイル内に、このような複数あるオブジェクトを配列の中に入れた書き方をします。 それを親であるCardComponentで読み込みます。 /CardComponent.tsx import items from './ItemDescription.json'; itemsとして一旦読み込みます。 そしてpropsとして渡す部分で、配列になったオブジェクトのそれぞれのKeyのValueを取得します。 /CardComponent.tsx return ( <div className={styles.card_component_wrapper}> <div> <CardItem title={items[0].title} year={items[0].year} description={items[0].description} /> </div> <div> <CardItem title={items[1].title} year={items[1].year} description={items[1].description} /> </div> <div> <CardItem title={items[2].title} year={items[2].year} description={items[2].description} /> </div> </div> ); これで別ファイルに分けたJSONファイルからデータを取得し表示する事ができました。 しかし毎回配列番号を何度も記述しなければならず、さらにJSONファイル内のデータの中身が変わった場合には、その都度配列番号を全て変更しないといけない事を考えるともう少しマシな書き方があるのではと思い、以下のようにリファクタリングしてみました。 /CardComponent.tsx import React from 'react'; import styles from './CardComponent.module.scss'; import CardItem from './CardItem'; import items from './ItemDescription.json'; const CardComponent: React.VFC = () => { const card1 = items[0]; const card2 = items[1]; const card3 = items[2]; const card4 = items[3]; return ( <div className={styles.card_component_wrapper}> <div> <CardItem title={card1.title} year={card1.year} description={card1.description} /> </div> <div> <CardItem title={card2.title} year={card2.year} description={card2.description} /> </div> <div> <CardItem title={card3.title} year={card3.year} description={card3.description} /> </div> </div> ); }; export default CardComponent; 正直、これに関しては完全に我流なのでもっと綺麗な書き方がありましたらぜひ教えてください。 我流ではありますが、こちらでもきちんと機能しました。もしJSONファイル内のデータに何かしらの変更があった場合でもあらかじめ定義した部分の配列番号を変更すれば済みます。 まとめ JSONファイルを用いて外部にデータを分けるメリットとして以下のことが挙げられます。 1. アプリの構造とデータを分けて管理できるので全体の見通しが良くなる。 2. データに変更があった場合に変更を加えやすい。保守性が高い こちらのコードはReactとTypescriptを使ってコードを書いていますが、今回お伝えした件に関しては言語に関係なくJSONファイルを扱うという点においては基本的に同じ考え方だと思いますので、初学者の方は是非参考にしてみてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gatsbyでロケーション情報を参照する方法

皆さんこんにちは! 最近学校やらプライベートやらで自分の時間が取れず投稿頻度が落ちたのですが、ちゃんと合間の時間を縫って勉強しております。 さて、今日は現在学習中のGatsby.jsにて現在いるパスやURLなどのロケーション情報を参照したいと思ったので備忘録として書いていきます。 結論から言うと、めちゃめちゃ簡単です! Reactでロケーション情報を参照するときはhistoryとかを使うと思うのですが、このようなプラグインのインストールや面倒な設定は一切行いません。 百聞は一見に如かずということで、例を見ていきましょう! locationプロパティ なんとGatsby.jsにはデフォルトでロケーション情報を参照することができます コンポーネントの引数でlocationを指定してあげましょう! import React from "react" const Example = ({ location }) => { console.log(location) return ( <></> ) } export default Example そうすると以下のような情報がログに出力されます。 hash: "###############" host: "localhost:8000" hostname: "localhost" href: "http://localhost:8000/example" key: "initial" origin: "http://localhost:8000" pathname: "/example" port: "8000" protocol: "http:" search: "" state: null なんて楽なんだと脱帽しました。。。 逆にこんな簡単にできていいのかと不安になりますが、余計なことは考えないようにします。 以上、「Gatsbyでロケーション情報を参照する方法」でした! Thank you for reading
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む