react講座 リストと key

react list and key

Reactでリストを作成する前に、JavaScript でリストを変換する方法についておさらいしましょう。 以下のコードでは、map() 関数を用い、numbers という配列を受け取って中身の値を 2 倍にしています。map() 関数が返す新しい配列を変数 doubled に格納し、ログに出力します: このコードはコンソールに [2, 4, 6, 8, 10] と出力します。 React で配列を要素のリストに変換する方法は上記に似ています。 複数のコンポーネントをレンダーする 要素の集合を作成し中括弧 {} で囲むことで JSX に含めることができます。 以下では、JavaScript の map() 関数を利用して、numbers という配列に対して反復処理を行っています。それぞれの整数に対して <li> 要素を返しています。最後に、結果として得られる要素の配列を listItems に格納しています: そして、listItems という配列全体を <ul> 要素の内側に含めます: このコードは、1 から 5 までの数字の箇条書きのリストを表示します。 基本的なリストコンポーネント 通常、リストは何らかのコンポーネントの内部でレンダーすることをが実用的です。 前の例をリファクタリングして、numbers という配列を受け取って要素のリストを出力するコンポーネントを作ることができます。 このコードを実行すると、「リスト項目には key を与えるべきだ」という警告が表示されます。“key” とは特別な文字列の属性であり、要素のリストを作成する際に含めておく必要があるものです。なぜ key が重要なのかは後に説明します。 numbers.map() 内のリスト項目に key を割り当てて、key が見つからないという問題を修正しましょう。 Key Key は、どの要素が変更、追加もしくは削除されたのかを React が識別するのに必要になります。配列内の項目に安定した識別性を与えるため、それぞれの項目に key を与えるべきです。 Keyはリレーショナルデータベースでいうプライマリーキーと同じイメージになります。いわば、ユニークなIDのことです。これで同じデータ(例:”田中さん”、”田中さん”)が複数あってもどのデータを指しているのかを判断できるようになりますね。 データ間でその項目を一意に特定できるような文字列を key として選ぶのが最良の方法です。多くの場合、のデータ内にある ID を key として使うことになるでしょう: レンダーされる要素に安定した ID がない場合、最終手段として項目のインデックス(順番)を使うことができます: 要素の並び順が変更される可能性がある場合、インデックスを key として使用することはお勧めしません。パフォーマンスに悪い影響を与え、コンポーネントの状態に問題を起こす可能性があるからです。もし明示的に key … Read more

react講座 条件付きレンダー

react 条件付きレンダー

React ではロジックをカプセル化した独立したコンポーネントを作ることができます。そして、あなたのアプリケーションの状態に応じて、その一部だけを更新、表示することが可能です。 React における条件付きレンダーは JavaScript における条件分岐と同じように動作します。if もしくは条件演算子のような JavaScript 演算子を使用して現在の状態を表す要素を作成すれば、React はそれに一致するように UI を更新します。 以下の 2 つのコンポーネントを見てみましょう。 ユーザがログインしているかどうかによって、これらのコンポーネントの一方だけを表示する Greeting コンポーネントを作成しましょう: この例では isLoggedIn プロパティの値によって異なる挨拶メッセージを表示します。 要素変数 要素を保持しておくために変数を使うことができます。これは、出力の他の部分を変えずにコンポーネントの一部を条件付きでレンダーしたい時に役立ちます。 ログアウトとログインボタンを表す以下の 2 つの新しいコンポーネントを考えましょう: 以下の例では、LoginControl というステート付きコンポーネントを作成します。 LoginControl は現在の state によって <LoginButton /> もしくは <LogoutButton /> の一方をレンダーします。加えて、前の例の <Greeting /> もレンダーします: Try it on CodePen 変数を宣言して if 文を使用することはコンポーネントを条件的にレンダーするなかなか良い方法ではありますが、より短い構文を使いたくなる時もあります。以下で述べるように、JSX でインラインで条件を記述する方法がいくつか存在します。 論理 && 演算子によるインライン If 中括弧で囲むことで、JSX に式を埋め込むことができます。これには JavaScript の論理 && 演算子も含まれます。これは条件に応じて要素を含めたいというときに便利です。 Try it on CodePen これが動作するのは、JavaScript では true && expression は必ず expression と評価され、false && expression は必ず false と評価されるからです。 従って、条件部分が true であれば、&& の後に書かれた要素が出力に現れます。もし false であれば、React はそれを無視して飛ばします。 falsy … Read more

React講座 イベント処理

react イベント処理

React でのイベント処理は DOM 要素のイベントの処理と似ています。まずは、いくつかの文法的な違いがあるので見ておきましょう。 例として、以下の HTMLを見てください。 は、React では少し異なります: 別の違いとして、React では false を返してもデフォルトの動作を抑止することができません。明示的に preventDefault を呼び出す必要があります。例えば、プレーンな HTML では、「フォームをサブミットする」という form 要素のデフォルト動作を抑止するために次のように書くことができます。 React では、代わりに次のようになります: ここで、e は合成 (synthetic) イベントです。React はこれらの合成イベントを W3C の仕様に則って定義しているので、ブラウザ間の互換性を心配する必要はありません。React のイベントはネイティブのイベントと全く同様に動作するわけではありません。 React を使う場合、一般的には DOM 要素の生成後に addEventListener を呼び出してリスナを追加する必要はありません。代わりに、要素が最初にレンダーされる際にリスナを指定するようにしてください。 コンポーネントを ES6 のクラスを使用して定義した場合、一般的なパターンではイベントハンドラはクラスのメソッドになります。例えば、以下の Toggle コンポーネントはユーザが “ON” 状態 “OFF” 状態を切り替えられるようなボタンをレンダーします。 JSX のコールバックにおける this の意味に注意しなければなりません。JavaScript では、クラスのメソッドはデフォルトではバインドされません。this.handleClick へのバインドを忘れて onClick に渡した場合、実際に関数が呼ばれた時に this は undefined となってしまいます。 これは React に限った動作ではなく、JavaScript における関数の仕組みの一部です。一般的に、onClick={this.handleClick} のように () を末尾に付けずに何らかのメソッドを参照する場合、そのメソッドはバインドしておく必要があります。 bind の呼び出しが苦痛である場合、それを回避する方法が 2 つあります。パブリッククラスフィールド構文を使えば、コールバックを正しくバインドすることができます: この構文は、Create React App ではデフォルトで有効です。 クラスフィールド構文を使用しない場合、コールバック内でアロー関数を使用することもできます: この構文での問題は、LoggingButton がレンダーされるたびに異なるコールバック関数が毎回作成されるということです。大抵のケースではこれは問題ありません。しかし、このコールバックが props の一部として下層のコンポーネントに渡される場合、それら下層コンポーネントが余分に再描画されることになります。 一般的にはコンストラクタでバインドするかクラスフィールド構文を使用して、この種のパフォーマンスの問題を避けるようおすすめします。 イベントハンドラに引数を渡す ループ内では、イベントハンドラに追加のパラメータを渡したくなることがよくあります。例えば、id という行の ID がある場合、以下のどちらでも動作します: 上記の … Read more

react講座 state とライフサイクル

React ライフサイクル

この章では React コンポーネントにおける state(状態) とライフサイクルについての導入を行います。 以前の章のひとつにあった秒刻みの時計の例を考えてみましょう。要素のレンダーの章にて、UI を更新するための方法をひとつだけ学びましたね。それはレンダーされた出力を更新するために root.render() を呼び出す、というものでした。 このセクションでは、この Clock コンポーネントを実用的に再利用可能かつカプセル化されたものにする方法を学びます。コンポーネントが自身でタイマーをセットアップし、自身を毎秒更新するようにします。 では時計の見た目をカプセル化するところから始めてみましょう: しかし上記のコードは重要な要件を満たしていません:Clock がタイマーを設定して UI を毎秒ごとに更新するという処理は、Clock の関数内で実現されるべきだということです。 理想的には以下のコードを一度だけ記述して、Clock に自身を更新させたいのです: これを実装するには、Clock コンポーネントに “ステート (state)” を追加する必要があります。 state は props に似ていますが、コンポーネントによって完全に管理されるプライベートなものです。 stateは状態管理の倉庫とイメージしてください。例えば気温のデータや不動産の値段など、ユーザーが入力したり、データを参照できるようなものです。 関数をクラスに変換する 以下の 5 ステップで、Clock のような関数コンポーネントをクラスに変換することができます。 これで、Clock は関数ではなくクラスとして定義されるようになりました。 render メソッドは更新が発生した際に毎回呼ばれますが、同一の DOM ノード内で <Clock /> をレンダーしている限り、Clock クラスのインスタンスは 1 つだけ使われます。このことにより、ローカル state やライフサイクルメソッドといった追加の機能が利用できるようになります。 クラスにローカルな state を追加する 以下の 3 ステップで date を props から state に移します: 親クラスのコンストラクタへの props の渡し方に注目してください: クラスのコンポーネントは常に props を引数として親クラスのコンストラクタを呼び出す必要があります。 タイマーのコードはコンポーネント自身に後で追加しなおします。 結果は以下のようになります: 次に、Clock が自分でタイマーを設定し、毎秒ごとに自分を更新するようにします。 クラスにライフサイクルメソッドを追加する 多くのコンポーネントを有するアプリケーションでは、コンポーネントが破棄された場合にそのコンポーネントが占有していたリソースを解放することがとても重要です。つまりは使わなくなったコンポーネントを外すという事になります。 タイマーを設定したいのは、最初に Clock が DOM として使用されるときです。このことを … Read more

React講座 コンポーネントとProps

React コンポーネントとprops

コンポーネントにより UI を独立した再利用できるパーツに分割し、パーツそれぞれを分離して考えることができるようになります。今回はコンポーネントという概念を理解できることを目標にしましょう。 関数コンポーネントとクラスコンポーネント コンポーネントを定義する最もシンプルな方法は JavaScript の関数を書くことです: この関数は、データの入った”props”プロパティというオブジェクトを引数として受け取り、React要素を返します。これがコンポーネントになります。 プロパティは親からもらうプレゼントをイメージしてください。そのプレゼントには何かのデータが入っていることをイメージしましょう。※propsは常に親から子です。子のコンポーネントから親コンポーネントにpropsが渡ることはありませんので覚えておきましょう。 classを使ってコンポーネントを定義することもできます。 細かいコンポーネントの構成については次回以降に説明をするので、再度コンポーネントの概念について理解を深めていきましょう。 コンポーネントのレンダー ここまでは、DOMのタグを使うReact要素のみを使いました。 しかし、要素はユーザー定義のコンポーネントを使用することもできます。 React がユーザ定義のコンポーネントを見つけた場合、JSX に書かれている属性と子要素を単一のオブジェクトとしてこのコンポーネントに渡します。このオブジェクトのことを “props” と呼びます。 例えば以下のコードではページ上に “Hello, Sara” を表示します: この例で何が起こるのかおさらいしてみましょう。 補足: コンポーネント名は常に大文字で始めてください。 React は小文字で始まるコンポーネントを DOM タグとして扱います。例えば、<div /> は HTML の div タグを表しますが、<Welcome /> はコンポーネントを表しており、スコープ内に Welcome が存在する必要があります。 コンポーネントを組み合わせる コンポーネントは自身の出力の中で他のコンポーネントを参照できます。これにより、どの詳細度のレベルにおいても、コンポーネントという単一の抽象化を利用できます。ボタン、フォーム、ダイアログ、画面:React アプリでは、これらは共通してコンポーネントとして表現されます。 例えば、Welcome を何回もレンダーする App コンポーネントを作成できます: 典型的には、新規の React アプリは階層の一番上に単一の App コンポーネントを持っています。しかし、既存のアプリに React を統合する場合は、Button のような小さなコンポーネントからボトムアップで始め、徐々にビューの階層構造の頂上に向かって進んでいってもよいでしょう。 コンポーネントの抽出 では、コンポーネントがどのように構成されるか分かったところで、どの段階でコンポーネントにするか悩みますよね。しかし、コンポーネントをより小さなコンポーネントに分割することを恐れる必要はありません。 例えば、この Comment コンポーネントについて考えましょう: これは props として author(オブジェクト)、text(文字列)、および date(日付)を受け取り、ソーシャルメディアサイトにおける … Read more

React講座 要素のレンダー

React要素の使い方

要素(エレメント)とは React アプリケーションの最小単位の構成ブロックです。 ブラウザのDOM要素と異なり、React要素は単純なオブジェクトになり、簡単に作成されます。React DOMがReactエレメントを把握してそれに従いDOMを更新する作業を担当することになります。 補足: 要素のことを、より広く知られている概念である “コンポーネント” と混同する人もいるかもしれません。コンポーネントについては次の章で説明します。要素とはコンポーネントを “構成する” ものです。次に進む前にこの章を読んでいくことをお勧めします。 要素を DOM としてレンダーする HTMLファイルの中に<div>要素があったとしましょう。 最初の記事で説明したようにindex.htmlにはrootの要素が一つだけありましたね。 ここにReactDOMがすべてのReactのアプリケーションを管理することになるのでルートのDOMノードと呼ぶことにしましょう。 Reactだけで構築されたアプリケーションはDOMノードを一つだけ持ちます。既存のアプリにReactを組み合わせて使いたい場合は独立したDOMノードを複数使用することも可能です。 React 要素をルート DOM ノードにレンダーするには、まず ReactDOM.createRoot() に DOM 要素を渡し、root.render() に React 要素を渡します。 このコードにより”Hello World”が表示されます。 レンダーされた要素の更新 react要素はイミュータブルです。※イミューン(Immune:変更できない) 一度作成された要素の子要素や、属性などを変更することはできません。 今の学習段階でUIを更新する方法は新し要素を作成してroot.render()に渡すという事になります。 以下の例で秒刻みに動く時計の例についてみてみます。 実際の例を見てください。 この例ではsetInterval() のコールバックから root.render() を毎秒呼び出しています。 補足: 上記のコードは例として記載したものであり、実際にはroot.render()を呼び出すことは1度のみ行う事が通常になります。次の章では、上記のコードをstate付きのコンポーネントへとカプセル化する方法を学びます。飛ばさないようにしましょう。 React は必要な箇所のみを更新する ReactDomは要素とその子要素を以前のものと比較しています。その比較の際に差があった場合、必要な部分のみのDOMの更新を行うことになります。 下記の例では時間の変わる要素の部分のみ更新されていることが分かりますね。 このように必要な部分だけリアクティブに要素が変わることでユーザーにインタラクティブなインターフェイスを提供することができますね。

React講座 JSXの使い方

React JSXの使い方

ではReactの仕組みを理解したところでReactのテンプレートシンタックスのJSXを理解していきましょう。 JSXはこのように書くことができます。ストリングでもないのでクオートで囲う必要もありません。 JSXを使わない方法もありますが、Reactを使う上ではJSXを是非使っていきたいです。 JSXはReactのエレメントを作成して、そこからDOMに変換されるようになります。 JSXを使う理由 Reactはイベントへのリスポンスや状態の変化を感知してユーザー側に表示するデータをリアクティブに作成することができます。 Reactの強みでもあるのがこのロジックとマークアップ(HTML)を同じファイルに記述できることです。ファイルが別々でないので一目で見ただけで何がユーザー側に表示されるか理解しやすいです。 この概念をコンポーネントと呼びます。 JSXに式を埋め込む では、次の例を見てみましょう。 nameという変数を宣言し、中括弧{}に入れることでJSX内で使用することができます。 この方法を使うことで、計算式の2+2やオブジェクト(例:user.name)を使うことができます。 JSXは長く記載する場合もあるので()で囲むようにするとよいです。 JSX自体を式として使う 先ほどはJSXに変数を入れる方法を紹介しました。 さらに、JSX自体も式としてif文やforループの文で使用することができます。 ReactがJSXを読み込む際にコンパイルされ普通のJavaSxriptに変換されるようになります。 JSXで属性を指定する 文字列リテラルを属性として指定するために引用符(クオーテーション)を使用できます。 これでHTMLの属性(attribute)にストリングの値を入れてあげることができます。 また、属性に JavaScript 式を埋め込むために中括弧を使用することもできます。これでダイナミックなデータを流し込むことができますね。 注意しておきたいこと JSXはHTMLよりもJavaScriptに近いものになります。ですのでHTMLの属性にclassを入れたい場合はJavaScriptのclassと干渉することを防ぐためにclassNameを使うことになります。 JSXで子要素を指定 タグが空の場合は、XMLのように/>でタグを閉じることができます。 もちろんJSXのタグに子要素(HTMLのタグ、エレメント)を入れることができます。 JSX はインジェクション攻撃を防ぐ JSX にユーザの入力を埋め込むことは安全です: React DOMはJSXに埋め込まれた値をレンダー前にエスケープします。 →エスケープとは、HTML上で特殊文字を期待通りに表示するために施す処理のことです。 →特殊文字に指定されている文字は、割り当てられている記号を記述することで表示できます。 →例えば、<は<であったり、©は©など、特殊文字には必ず該当する記号が割り当たっています。 このため、XSS攻撃の防止になります。 JSXはオブジェクトの表現になる ReactがJSXをコンパイルする流れを見てみましょう。 下記の二つの例は同じものになります。 ①JSXの例 ②JSXを使わない例 上記のコードをReactのcreateElementメソッドで下記の様なオブジェクトを作成することになります。 このようなオブジェクトはReact要素(エレメント)と呼びます。Reactがこれらのオブジェクトを読み取り、必要に応じてDOMを構築し常にリアクティブなデータをユーザーに’届けるようになります。 では、次回は要素のレンダーについて学んでいきましょう。

React講座 Reactの仕組み

reactの仕組みを理解する

JavaScriptの基礎を学んで次に何をしたらよいか迷っている方、Web開発でスキルを上げたい方、Reactのフレームワークを是非学びましょう。 では、Reactのコンセプトのシリーズ第一章の始まりです。 Reactのアプリケーションをビルドする では、手元にテキストエディタとNode.jsがあることが条件です。(ここまでわからない人はJavaScriptの基本と) では、前回の記事で紹介したように、Reactのプロジェクトを作成しておきます。 Viteで作成する場合は同じコマンドだけ下記に記載しておきます。 index.html では、テキストエディタからファイル構成を見てみましょう。 index.htmlがプロジェクトの直下にありますね。 このHTMLはほぼ触る必要はありません。 CSSもJavaScriptもすべてアプリケーションをマウントする際に他のJavaScriptファイルから読み込ませるようにします。 このマウントというのはReactのアプリケーションを読み込む作業のことです。 ここでIdがrootのdivがあることに注目しましょう。 ここにすべてのReactのアプリケーションをマウントすることになります。 これはsrcフォルダ内のmain.jsxファイルを見ることで理解できます。jsxはJavaScriptのエクステンションのことで、JavaScript内でHTMLを書けるようにしたものです。詳しい説明は後から行います。 上記のコードを見ると、先ほどのHTMLのrootのidのところに<App/>というのをレンダーしていることが分かりますね。 ここにassets/App.jsxがマウントされているという事になります。 これがコンポーネントの概念になります。それぞれのJsxファイル内にコンポーネント(パーツ)となるものを作成して再利用できるところでマウントさせることができます。 ですので、ボタンのコンポーネントやフォームのコンポーネントを作成してどこでも再利用できるようになります。便利ですね。 では次にJSXについて説明したいと思います。

Djangoのデータベースのバックアップをスケジュール化する

Djangoのベータベースのバックアップとリストアをスケジュール化する

お疲れ様です。前回はDjangoのライブラリを使って簡単にDBのバックアップを取る方法を説明しました。

しかし、これを毎回手作業で行うのも面倒ですので、このタスクをスケジュール化する方法を紹介していきたいと思います。

今日の環境

  • 前回の記事で説明したdjango-dbbackupのライブラリがインストールされている状態
  • Ubuntu22.04(OSはあまり関係ないです)
  • Python3

ライブラリのインストール

では、下記のコマンドでdjango-crontabをインストールしていきます。LinuxかMacを使ったことがある人はなじみがあるかもしれません。タスクスケジューラーのDjango版です。

詳しい説明はこちらを見てください。

pip install django-crontab

#必要に応じてpip freeze > requirements.txt

次に、Djangoのプロジェクトファイルのsettings.pyのアプリの場所にこのライブラリを登録します。

INSTALLED_APPS = (
    'django_crontab',
    ...
)

cron.pyファイルの作成

では、タスクをスケジュール化するためのPythonファイルを作成します。

ファイル名をcron.pyでプロジェクトフォルダに作成しましょう。

cron_job.pyに仮のファンクションを入れておきます。

def backup_scheduled_job():
  pass

では、settings.pyに戻りこのスケジュールのタスクのファンクションを教えてあげます。

CRONJOBS = [
    ('*/5 * * * *', 'myapp.cron.my_scheduled_job')
]

#例2 ファンクションをインポート
#*****のところでスケジュールの時間を指定(今は五分ごとに設定)

CRONJOBS = [
    ('*/5 * * * *', 'djangoapi.cron.backup_scheduled_job')
]

cronjobを初めて使う人は*****の部分にどの数字を入れて、毎分、毎週とかでタスクをスケジュール化したいのか調べましょう。

このサイトが分かりやすいと思いました。

このサイトから見ても分かるように1****は毎分タスクを実行させることになります。

タスクの詳細を設定する

では、先ほどのcron.pyに戻り、タスクの内容を書いていきます。

from django.core.management import call_command

def backup_scheduled_job():
    try:
        call_command('dbbackup')
    except:
        pass

crontabのタスクを追加する

では、先ほど作成したタスクをDjangoに教えてあげます。

python manage.py crontab add

で、1分ほど待つと、バックアップファイルが作成されました!

タスクを削除したい場合は下記のコマンドになります。

python manage.py crontab remove

これで、settings.pyに設定されているcrontabのタスクがすべてスケジュールから外されます。

リストアをスケジュールしたい場合

リストアの場合は、本当にリストアしますか?というプロンプト(質問)が聞かれるのでそれをバイパスしてあげる必要があります。

def restore_scheduled_job():
    try:
        call_command('dbrestore', '--noinput')
    except:
        pass

これで、先ほどと同じようにスケジュールを設定すると、毎分データベースがリストアされます。

お疲れさまでした。

Djangoのデータベースを正しくバックアップ、リストアする

Djangoのデータベースをバックアップ

Djangoのアプリをデプロイするのは良いですが、大切なデータは守りたいですよね。

今日はPythonのウェブフレームワーク、Djangoで作成したアプリケーションのデータベース(PostgreSQL)のデータベースをバックアップする方法を紹介します。

データベースのバックアップ

通常データベースのバックアップには下記の様な方法があります。

  • pg_dumpのコマンドを使ってダンプファイルを抽出する。
  • Djangoについてくるsqlclear/sqlallのコマンドを使う。
  • Djangoについてくるdumpdata/loaddataのコマンドをつかう。

正しくDjangoのデータのバックアップを取る

上記のやり方には不備があります。

これらの方法だと、メディアファイル、つまり、FileFiledを使ってアップロードされたデータはバックアップに含まれません。

更に、Python manage.py migrateのコマンドで作成されるテーブル、つまりはパーミッション、セッションはバックアップに含まれません。

ですので、今日紹介するライブラリを使って簡単に正しいバックアップを取るようにしましょう。

django-dbbackupをインストールする

では、django-dbbackupのライブラリをインストールします。

下記にリンクを付けるので参考にしてください。

https://pypi.org/project/django-dbbackup/

pip install django-dbbackup

#おまけです。
pip freeze > requirements.txt

次にプロジェクトのsettings.pyファイルに下記の様にインストールしたアプリを追加します。

INSTALLED_APPS = (
    ...
    'dbbackup',  # django-dbbackup
)

DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage'
DBBACKUP_STORAGE_OPTIONS = {'location': '/my/backup/dir/'}

バックアップを置く場所は下記の様に指定してもOKです。

DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage'
DBBACKUP_STORAGE_OPTIONS = {'location': BASE_DIR/'dump'}

dumpフォルダーを作成しました。ここにbackupを置くようにします。

バックアップをとる

ではこれでOK。下記のコマンドでバックアップが取れるか試してみましょう。

python manage.py dbbackup

バックアップファイルができました!

バックアップからデータをリストア

では、試しにデータを変えてみます。レコードを一つ追加してみました。

では、コマンドラインからバックアップを使ってデータをリストアしてみましょう。

このコマンドで一番新しいバックアップのファイルを使ってデータベースを上書きします。

python manage.py dbrestore

お見事!

データがバックアップの値に戻りました。

お疲れ様です。