React は DI という考え方が存在しないライブラリとなっています。
DI できなくとも jest のモック関数の機能を使えばテストに困ることもほとんどありません。
そうはいっても DI 可能な Hooks・コンポーネントにしたい場合は、以下のようにすれば実現可能です。
...React は DI という考え方が存在しないライブラリとなっています。
DI できなくとも jest のモック関数の機能を使えばテストに困ることもほとんどありません。
そうはいっても DI 可能な Hooks・コンポーネントにしたい場合は、以下のようにすれば実現可能です。
...以下の本を読んだ。あとで見返したいところについてメモを残しておく。
要求の変更によって引き起こされる問題に取り組むため、そして機能分解以外の解決策の有無を見極めるために、人間の行動に目を向けてみましょう。とある大学で開催されるセミナーの講師として、あなたが任命されたと考えてください。あなたの講義を聞き終わった学生は、次のセミナーが行われる教室に移動しなければなりませんが、それは各人によってまちまちであると仮定します。そしてあなたは、聴講学生各人に対して次の教室への行き方を教えなければならないとします。
...運用しているウェブサイトについて死活監視をしたく、次のような要件で調べた結果 UptimeRobot がとても良かったので記録しておきます。
監視の分野は全く詳しくないため、そもそもどういったワードで調べれば良いか悩みました。
...Lightsail の最も安いプランだと月額 3.50 USD でインスタンスが運用できます。小規模なウェブサイトであればこれで全然運用できるのではないでしょうか。
当然ながら格安な分、サーバのスペックも低めなわけで、特にメモリがなんとも心許ないです。
...インプットフォームを作成する際、React では「制御されたコンポーネント(Controlled Components)」と「非制御コンポーネント(Uncontrolled Components)」という2つの考え方があります。
...Flutter で UUID のパッケージを使っているときに疑問に感じたことがありました。
それがこんな場面です。
import 'package:uuid/uuid.dart';
void main() {
var myId = const Uuid().v4();
/*
myId を使って処理をする
*/
}
ここで思ったことが Uuid()
に const
をつけることができるが、const
はコンパイル時定数のはずだから、コンパイル後の myId
の値は常に同じになってしまうのでは?というものです。
掲題について、根本的に勘違いしていたので、反省も込めてここにメモ。
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const MyWidget1(),
routes: <String, WidgetBuilder>{
'/mywidgeet1': (BuildContext context) => const MyWidget1(),
'/mywidgeet2': (BuildContext context) => const MyWidget2(),
},
);
}
}
/*
MyWidget1
*/
class MyWidget1 extends StatefulWidget {
const MyWidget1({super.key});
@override
State<MyWidget1> createState() => _MyWidgetState1();
}
class _MyWidgetState1 extends State<MyWidget1> {
int myCount1 = 0;
@override
void initState() {
super.initState();
myCount1++;
print('myCount1 was incremented to $myCount1');
}
@override
Widget build(BuildContext context) {
print('MyWidget1 was built');
return TextButton(
onPressed: () => Navigator.of(context).pushNamed("/mywidgeet2"),
child: const Text('Push'),
);
}
}
/*
MyWidget2
*/
class MyWidget2 extends StatefulWidget {
const MyWidget2({super.key});
@override
State<MyWidget2> createState() => _MyWidgetState2();
}
class _MyWidgetState2 extends State<MyWidget2> {
int myCount2 = 0;
@override
void initState() {
super.initState();
myCount2++;
print('myCount2 was incremented to $myCount2');
}
@override
Widget build(BuildContext context) {
print('MyWidget2 was built');
return TextButton(
onPressed: () => Navigator.of(context).pop("/mywidgeet1"),
child: const Text('Pop'),
);
}
}
# 初期表示時
myCount1 was incremented to 1
MyWidget1 was built
# MyWidget1 から myCount2 に push()
myCount2 was incremented to 1
MyWidget2 was built
# MyWidget2 から myCount1 に pop()
(なにも出力されない)
# MyWidget1 から myCount2 に push()
myCount2 was incremented to 1
MyWidget2 was built
# MyWidget2 から myCount1 に pop()
(なにも出力されない)
Flutter のページ遷移は push() & pop()
でページの上にページを重ねていく形(または重ねたものを上から取り除く形)になります。
以下の本を読んだ。あとで見返したいところについてメモを残しておく。
*記事中のコードの言語は Kotlin です。
再構成メソッドは、プロダクトコードではリポジトリ実装クラスで DB の値からインスタンス再構成する場合のみ使用します。
...以下の本を読んだ。あとで見返したいところについてメモを残しておく。
モデルとは現実の事象あるいは概念を抽象化した概念です。抽象は抽出して象るという言葉のとおり、現実をすべて忠実に再現しません。必要に応じて取捨選択を行います。何を取捨選択するかはドメインによります。
...以下の本を読んだ。あとで見返したいところについてメモを残しておく。
業務アプリケーションで数量を扱うとき、int
のすべての範囲(マイナス 21 億からプラス 21 億)が必要になることはありません。「0 より大きく 100 より小さい」など、もっと狭い範囲の値が業務的に正しい値です。
以下の本を読んだ。あとで見返したいところについてメモを残しておく。
ドメイン層のオブジェクトを設計する際に、重要な基本方針があります。
...本記事に登場するコードの言語は C#
です。
サービスロケータや DI の話に入る前に、まずは何もできていない状態です。
public class Model
{
private readonly IRepository _repository;
public Model()
{
this._repository = new Repository();
}
}
Model model = new Model();
サービスロケータパターンとは要するに以下です。
...Mac で C# の実行環境を作成したい場合、方法は2つあります。
どちらの方法にするかは、使用したいエディタによって決めてしまうと良いでしょう。
...ワードプレスの移行というと「All-in-One WP Migration」プラグインが利用されるケースを多く見かけます。ただしこちらのプラグインでは、無料版の場合だと移行元データを移行先にインポートするときの容量に上限が設けられています。(有料版を契約せずとも、無料版のままこの制限を解除する方法もあるようです。)
...たとえば npm でプライベートなパッケージを作成していて、他のリポジトリのアプリがそのパッケージを利用しているとします。
プライベートなパッケージにアクセスするにはアクセストークンが必要です。
...毎回のプルリク後に Assignees を手動でポチポチ設定するのが若干の手間だと感じていたところ、素晴らしい記事に巡り合いました。
現在は、上記の記事から actions/github-script
の最新バージョンが上がっていたり(本記事時点での最新は v6)、そのほか微調整を加えたのが以下です。
Riverpod を使い始めて間もないころだと、Provider、StateProvider、StateNotifierProvider の違いについて混乱する人もいるのではないでしょうか。
...のっぴきならない事情があってファイルの作成日・更新日を変更したいときは setfile
コマンドが使えます。
setfile -d "12/24/2020 19:00" example.txt
setfile -m "12/24/2020 19:00" example.txt
-d
オプションで作成日を変更、-m
オプションで更新日を変更します。
GitHub Actions で Flutter の Lint(Analyzer)と Formatter と Test を実行するようにワークフローを作成します。
先に完成したコードを掲載し、その後解説します。
.github/
├ actions/
│ └ action.yaml
└ workflows/
└ main.yaml
.github/actions/action.yaml
#
# This is a "Composite action" or "Composite Run Steps" file.
runs:
using: 'composite'
steps:
- name: 'Setup Flutter'
uses: subosito/flutter-action@v2
with:
flutter-version: '3.x'
channel: 'stable'
cache: true
- name: 'Show Flutter version'
run: flutter --version
shell: bash
- name: 'Install dependencies'
run: flutter pub get
shell: bash
.github/workflows/main.yaml
#
name: 'Static Analysis and Testing'
on:
pull_request:
jobs:
Analyzer:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions
- run: flutter analyze
Formatter:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions
- run: flutter format --output=none --set-exit-if-changed .
Test:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions
- run: flutter test lib
上記のワークフローでは Analyzer と Formatter と Test という3つのジョブを実行しています。それぞれ以下の通りです。
...通常の場合 Flutter のテストを実施するには次のコマンドを実行します。
flutter test
この場合は test/
ディレクトリ配下のテストファイルが実行されます。
The test runner considers any file that ends with
..._test.dart
to be a test file. If you don’t pass any paths, it will run all the test files in yourtest/
directory, making it easy to test your entire application at once.
Flutter プロジェクト新規作成直後の analysis_options.yaml
は下記になっています。実質 include: package:flutter_lints/flutter.yaml
しているだけの状態です。
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
#
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
そして package:flutter_lints/flutter.yaml
は内部で package:lints/recommended.yaml
を import
し、さらにそれが package:lints/core.yaml
を import
しています。