Noneとエラー処理

fn main() {
	let mut data = vec![];
	for n in 0..5 {
		data.push(Some(n));
	}
	print_all(data);
}

fn print_all(data:Vec<Option<i32>>) {
	for item in data {
		println!("{:?}", item);
	}
}

Noneを含む処理

use rand::Rng;

fn random()-> Option<i32> {
	let n = rand::thread_rng().gen_range(0..10);
	match n {
		0 => None,
		_ => Some(n)
	}
}

fn main() {
	let mut data = vec![];
	for n in 0..10 {
		data.push(random(n));
	}
	print_all(data);
}

fn print_all(data:Vec<Option<i32>>) {
	for item in data {
		print(item);
	}
}

fn print(item:Option<i32>){
	match item {
		None => println!("no-data..."),
		Some(n) => println!("No, {}.", n)
	}
}

### Panicによる強制終了

fn print(item:Option<i32>){
	match item {
		None => panic!("NODATA!"),
		Some(n) => println!("No, {}.", n)
	}
}

### Resultによるエラーリカバリ

enum Result<T,E>{
	Ok(T),
	Err(E),
}

Errを使ってエラー処理を行う

fn print(item:Option<i32>)->Result<String, String>{
	match item {
		None => {
			Err(String::from("ERROR IS OCCURED."))
		},
		Some(n) => {
			println!("No, {}.", n);
			Ok(String::from("OK"))
		}
	}
}

### print_allでResultによるエラー処理を実装

fn print_all(data:Vec<Option<i32>>) {
	for item in data {
		let res = print(item);
		match res {
			Ok(s) => println!("--- {} ---", s),
			Err(s) => println!("*** {} ***", s)
		}
	}
}

### より細かなエラー処理
enum ErrKin {
Caution,
Danger
}

fn print_all(data:Vec<Option<i32>>) {
	for item in data {
		let res = print(item);
		match res {
			Ok(s) => println!("--- {} ---", s),
			Err(s) => match k {
				ErrKind::Caution => {
					println!("*** CAUTION!! ***");
				},
				ErrKind::Danger => {
					println!("DANGER!!");
					panic!("DANGER ERROR.");
				}
			}
		}
	}
}

fn print(item:Option<i32>)->Result<String, ErrKind>{
	match item {
		None => {
			Err(ErrKind::Danger)
		},
		Some(n) => {
			println!("No, {}.", n);
			if n == 1 {
				Err(ErrKind::Caution)
			} else {
				Ok(String::from("OK"))
			}
		}
	}
}

Rustジェネリクス

様々な型に対応できる処理に対応できるのがジェネリクス

#[derive(Debug)]
struct Sample<T> {
	name:String,
	value:T
}

fn main() {
	let taro = Sample {
		name:String::from("Taro"),
		value:String::from(("this is message."))
	};
	let hanako = Sample {
		name:String::from("Hanako"),
		value: 1234
	};
	println!("{:?}", taro);
	println!("{:?}", hanako);
}

SampleにVecフィールドを追加する

#[derive(Debug)]
struct Sample<T:core::fmt::Debug> {
	name:String,
	value:Vec<T>
}

impl<T:core::fmt::Debug> Sample<T> {
	fn print_values(&self) {
		println!("*** {} ***", &self.name);
		for item in &self.values {
			println!("{:?}", item);
		}
	}
}

fn sample<T:core::fmt::Debug>(name:&str, values:Vec<T>)
	-> Sample<T>{
		Sample{name:String::from(name), values:values}
	}

fn main() {
	let taro = sample("Taro",
		vec![123, 456, 789]);
	taro.print_values();
	let hanako = sample("Hanako",
		vec!["Hello", "Welcome", "Bye!"]);
	hanako.print_values();
}
trait Print {
	fn print(&self) {
		println!("not implmented...");
	}
}

struct Person {
	name: String,
	mail: String,
	age: i32
}

struct Student {
	name: String,
	mail:String,
	grade: i32
}

impl Print for Person {
	fn print(&self) {
		println!("Person: {}<{}>({})", &self.name, &self.mail, &self.age);
	}
}

impl Print for Student {
	fn print(&self) {
		println!("Student [grade {}]{}<{}>", &self.grade, &self.name, &self.mail);
	}
}

fn person(name:&str, mail:&str, age:i32)->Box<Person>{
	Box::new(Person{name:String::from(name), mail:String::from(mail), age:age})
}

fn student(name:&str, mail:&str, grade:i32)->Box<Student>{
	Box::new(Student{name:String::from(name), mail:String::from(mail), grade})
}

Rustトレイト

トレイトは実装を抽象化したもの
trait トレイト {
fn 関数(引数);
fn 関数(引数);
}

trait Print {
	fn print(&self);
}

struct Person {
	name:String,
	mail:String,
	age:i32
}

impl Print for Person {
	fn print(&self) {
		println!("{}<{}>({}).", self.name, self.mail, self.age);
	}
}

fn person(name:String, mail:String, age:i32)-> Person {
	Person {name, mail, age}
}

struct Student {
	name:String,
	mail:String,
	grade:i32
}

impl Print for Student {
	fn print(&self) {
		println!("grade{}: {}<{}>.", self.grade, self.name, self.mail);
	}
}

fn student(name:String, mail:String, grade:i32)-> Student {
	Student {name, mail, grade}
}

fn main(){
	let taro = person {
		String::from("Taro"),
		String::from("taro@yamada"),
		39
	};
	let hanako = person {
		String::from("Hanako"),
		String::from("hanako@flower"),
		28
	};
	taro.print();
	hanako.print();
}

### 汎用トレイトとderive属性

#[derive(Debug)]
struct Person {
	name:String,
	mail:String,
	age:i32
}

#[derive(Debug)]
struct Student {
	name:String,
	mail:String,
	grade:i32
}

fn person(name:&str, mail:&str, age:i32)->Person {
	Person{name:String::from(name), mail:String::from(mail), age:age}
}

fn student(name:&str, mail:&str, grade:i32)->Student {
	Student{name:String::from(name), mail:String::from(mail), grade}
}

fn main() {
	let taro = person("Taro", "taro@yamada", 39);
	let hanako = student("Hanako", "hanako@flower", 2);
	println!("{:?}", taro);
	println!("{:?}", hanako);
}
trait Print {
	fn print(&self) {
		println!("PRINT is not yet implemented...");
	}
}

#[derive(Debug)]
struct Person {
	name:String,
	mail:String,
	age:i32
}

#[derive(Debug)]
struct Student {
	name:String,
	mail:String,
	grade:i32
}

impl Print for Person {
	fn print(&self) {
		println!("{}<{}>({}).", self.name, self.mail, self.age);
	}
}

impl Print for Student {}

fn person(name:&str, mail:&str, age:i32)->Person {
	Person{name:String::from(name), mail:String::from(mail), age:age}
}

fn student(name:&str, mail:&str, grade:i32)->Student {
	Student{name:String::from(name), mail:String::from(mail), grade}
}

fn main() {
	let taro = person("Taro", "taro@yamada", 39);
	let hanako = student("Hanako", "hanako@flower", 2);
	taro.print();
	hanako.print();
}

Rust構造体

異なる型の値を決まった構造で管理する
struct 構造体名{
フィールド名: 型,
フィールド名: 型,

}

struct Person {
	name: String,
	mail: String,
	age: i32
}

fn print_person(p:Person) {
	println!("I'm {}({}). Mail to {}.", p.name, p.age, p.mail);
}

fn main(){
	let taro = Person {
		name:String::from("Taro"),
		mail:String::from("taro@yamada"),
		age: 39
	};
	let hanako = Person {
		name:String::from("Hanako"),
		mail:String::from("hanako@flower"),
		age: 28
	};
	print_person(taro);
	print_person(hanako);

}

### タプル構造体
構造体名の後にタプル()で記述する

struct Person (String, String, i32);

fn print_person(p:Person) {
	println!("I'm {}({}). Mail to {}.", p.0, p.2, p.1);
}

fn main(){
	let taro = Person (
		String::from("Taro"),
		String::from("taro@yamada"),
		39
	);
	let hanako = Person (
		String::from("Hanako"),
		String::from("hanako@flower"),
		28
	);
	print_person(taro);
	print_person(hanako);
}

構造体は値を保管するためのもの
implというブロックを使う

出力メソッドを実装

struct Person {
	name: String,
	mail: String,
	age: i32
}

fn person(name:String, mail:String, age)-> Person {
	Person {name, mail, age}
}

impl Person {
	fn print(&self) {
		println!("{}<{}>({}).", self.name, self.mail, self.age);
	}
}

fn main(){
	let taro = person {
		String::from("Taro"),

selfのない関数

struct Person {
	name: String,
	mail: String,
	age: i32
}

fn person(name:String, mail:String, age:i32)-> Person {
	Person {name, mail, age}
}

impl Person {
	fn print(&self) {
		println!("{}<{}>({}).", self.name, self.mail, self.age);
	}
	fn fields()->[String;3] {
		[
			String::from("name:String"),
			String::from("mail:String"),
			String::from("age:i32"),
		]
	}
}

fn main(){
	let taro = person {
		String::from("Taro"),
		String::from("taro@yamada"),
		39
	};
	let hanako = person {
		String::from("Hanako"),
		String::from("hanako@flower"),
		28
	};
	taro.print();
	hanako.print();
	println!("Person's fields: {:?}", Person::fields());
}

Rust所有権と参照

リテラルはプログラム内にハードコードされる

fn main(){
	let msg = "Hello!";
	let msg2 = msg;
	println!("{}", msg);
	println!("{}", msg2);
}

さまざまな値の所有権
L 所有権が移動するため、エラーになる

fn main(){
	let msg = String::from("Hello!");
	let msg2 = msg;
	println!("{}", msg);
	println!("{}", msg2);
}

数値の場合は参照している

関数の所有権

fn main(){
	let msg = String::from("Hello!");
	print_msg(msg);
	printl!("msg: {}", msg);
}

fn print_msg(msg:String) {
	println!("Message is {}", msg);
}

戻り値を設定して渡した関数から返してもらう

fn main(){
	let mut msg = String::from("Hello!");
	msg = print_msg(msg);
	println!("msg: {}", msg);
}

fn print_msg(msg:String)->String {
	println!("Message is \"{}\".", msg);
	msg
}

### 参照
値がある場所を示す
参照は利用した後にドロップされて破棄される

fn main(){
	let msg = String::from("Hello!");
	print_msg(&msg);
	println!("msg: {}", msg);
}

fn print_msg(msg:&String) {
	println!("Message is \"{}\".", msg);
}
fn main(){
	let msg = &String::from("Hello!");
	println!("msg: {}", msg);
	{
		let msg = print_msg(msg);
		println!("msg: {}", msg);
	}
	println!("msg: {}", msg);
}

fn print_msg(msg:&String)->String {
	let msg = String::from("*** ") + msg + " ***";
	println!("Message is \"{}\".", msg);
	msg
}

書き換え可能な値を参照で渡すことで参照した値を変更できます。

fn main(){
	let mut msg = String::from("Hello!");
	println!("msg: {}", msg);
	print_msg(&mut msg);
	println!("msg: {}", msg);
}

fn print_msg(msg:&mut String){
	msg.push_str("!!!!");
	println!("Message is \"{}\".", msg);
}

### スライス

fn main(){
	let msg = "Hello, world!";
	let world = &msg[7..12];
	println!("`{}` in `{}`.", world, msg);
}

可変文字列からのスライス

fn main(){
	let mut msg = String::from("Hello, world!");
	let world = &msg[7..12];
	println!("`{}` in `{}`.", world, msg);
	msg.insert_str(7, "RUST?");
	println!("`{}` in `{}`.", world, msg);
}

スライスを元に可変テキストを作る

fn main(){
	let mut msg = String::from("Hello, world!");

	let world = &msg[7..12];
	println!("`{}` in `{}`.", world, msg);
	msg.insert_str(7, "RUST?");
	
	let mut world = String::from(&msg[7..12]);
	world.push('!');
	println!("`{}` in `{}`.", world, msg);
}

配列スライス

fn main(){
	let data = [12,34, 56,78, 90];
	let part = &data[2..4];
	println!("{:?} in {:?}", part, data);
}
fn main(){
	let mut data = vec![12,34, 56,78, 90];
	let part = &data[2..4];
	data.insert(1, 999);
	println!("{:?} in {:?}", part, data);
}
fn main(){
	let mut data = vec![12,34, 56,78, 90];
	let mut part = data[2..4].to_vec();
	data.insert(1, 999);
	part.push(-1);
	println!("{:?} in {:?}", part, data);
}

Rust関数定義

fn main() {
	hello(String::from("taro"));
	hello(String::from("hanako"));
}

fn hello(name:String) {
	println!("Hello, {}!",name);
}

戻り値を持つ関数

fn main(){
	print_msg(100);
	print_msg(200);
	print_msg(300);
}

fn print_msg(max:i32){
	println!("{}までの合計は、{}です。", max, calc(max));
}

fn calc(max:i32)-> i32 {
	let mut result = 0;
	for n in 0..max {
		result += n;
	}
	result
}

### 値としての関数
定義に関数名がない匿名関数
変数 = |引数| {…処理…}

fn main(){
	let calc = |max| {
		let mut result = 0;
		for n in 0..max {
			result += n;
		}
		result
	};

	let print_msg = |max| {
		println!("{}までの合計は{}です。", max, calc(max));
	}

	print_msg(100);
	print_msg(200);
	print_msg(300);
}

### クロージャ
値として定義された匿名関数を変数に代入したものはクロージャという
元々、関数をオブジェクトとして利用できるようにする仕組み

fn main(){
	let max = 100;
	let res = calc(max);

	let print_msg = || {
		println!("{}までの合計は{}です。", max, res);
	};
	print_msg();

	let max = 200;
	let res = calc(max);
	let print_msg = || {
		println!("0-{} Total:{}", max, res);
	};
	print_msg();
}

fn calc(max:i32)-> i32 {
	let mut result = 0;
	for n in 0..max {
		result += n;
	}
	result
}

Rust複合型とコレクション

### 配列

fn main() {
	let data = [12, 34, 56, 78, 90];
	let mut ans = 0;
	for item in data {
		ans += item;
	}
	println!("データの合計は、{}です。", ans);
}

配列の型は[型;個数]となる。

### タプル

fn main() {
	let taro = ("Taro", 39, true);
	let hanako = ("Hanako", 28, false);
	println!("{:?}", taro);
	println!("{:?}", hanako);
	println!("name:{}, {}", taro.0, hanako.0);
	println!("age:{}, {}", taro.1, hanako.1);
	println!("male?:{}, {}", taro.2, hanako.2);
}

### ベクター型
同じ型の値を多数保管
空のVecを作成: Vec::new()
初期値を持つvecを作成: vec![値1, 値2, …]
値を取り出す: [番号], .get(番号), .get(番号).unwrap()
値を追加: .push(値)

fn main(){
	let mut data = Vec::new();
	data.push(123);
	data.push(456);
	data.push(789);
	println!("0:{}, 1:{}, 2:{}", data[0], data[1], data.get(2).unwrap());
}

### Vecの値を繰り返し処理する
ベクターはコレクションである

fn main(){
	let data = vec![123, 456, 789];
	let mut result = 0;
	for item in data {
		result += item;
	}
	println!("データの合計は、{}です。", result);
}

途中に値を挿入したい場合はinsertを使う
.insert(番号、値)

fn main(){
	let mut data = vec![123, 456, 789];
	data.remove(1);
	data.insert(2, 100);
	println!("{:?}", data);
}

### 名前で値を管理するHashMap
std::collectionsというモジュールで管理されている
use std::collections::HashMMap;

HashMapの作成:HashMap::new();
値を追加: .insert(名前, 値);
値を削除: .remove(名前);

use std::collections::HashMap;

fn main(){
	let mut map = HashMap::new();
	map.insert(String::from("first"), 123);
	map.insert(String::from("second"), 456);
	map.insert(String::from("third"), 789);
	map.remove("second");
	println!("{:?}", map);
}

HashMapは順不同、テキストリテラルではなくStringでテキストを指定
.get(名前).unwrap();

use std::collections::HashMap;

fn main(){
	let mut map = HashMap::new();
	map.insert(String::from("first"), 123);
	map.insert(String::from("second"), map["first"] * 2);
	map.insert(String::from("third"), map.get("first").unwrap() + map.get("second").unwrap());

	println!("{:?}", map);
}

HashMapの繰り返し処理
L for(ky, val) in map

use std::collections::HashMap;

fn main(){
	let mut map = HashMap::new();
	map.insert(String::from("first"), 123);
	map.insert(String::from("second"), 456);
	map.insert(String::from("third"), 789);
	let mut result = 0;
	for (ky, val) in map {
		println!("{}: {}.", ky, val);
		result += val;
	}

	println!("total: {}.", result);
}

### String型のテキスト

fn main() {
	let s1 = String::new();
	let s2 = String::from("Hello");
	let s3 = "World";
	let s4 = s1 + &s2 + &s3;
	println!("{}", s4);
}
fn main() {
	let mut s1 = String::new();
	s1.push_str("Hello");
	s1.push_str("World!");
	println!("{}", s1);
}
fn main() {
	let mut s1 = String::from("Hello,World!");
	s1.insert_str(6, " Rust ");
	s1.insert(7, '*');
	s1.insert(12, '*');
	s1.remove(5);
	println!("{}", s1);
}

### 文字の部分取得
レンジを使って文字列の中から一部分だけ取り出せる

fn main() {
	let s1 = String::from("Hello,Rust World!");
	let s2 = &s1[0..5];
	let s3 = &s1[6..10];
	let s4 = &s1[11..16];
	let s5 = String::new() + s4 + s3 + s2;
	println!("{}", s5);
}

Rust制御フロー

if文

fn main(){
	let num = 1234;
	if num % 2 == 0 {
		println!("{}は偶数です。", num);
	} else {
		println!("{}は奇数です。", num);
	}
}

比較演算式は、==, !=, <, <= など else ifによる条件式 [code] fn main(){ let num = 123; if num % 5 == 0 { println!("{}は5で割れます。", num); } else if num % 4 == 0 { println!("{}は4で割れます。", num); } else if num % 3 == 0 { println!("{}は3で割れます。", num); } else if num % 2 == 0 { println!("{}は2で割れます。", num); } else { println!("{}はうまく割れませんでした。", num); } } [/code] [code] fn main(){ let num:u8 = 7; match num { 1 => println!("{}月は、正月です。", num), 2 => println!("{}月は、節分です。", num), 3 => println!("{}月は、ひな祭りです。", num), 4 => println!("{}月は、入学式です。", num), 5 => println!("{}月は、ゴールデンウィークです。", num), 6 => println!("{}月は、梅雨です。", num), 7 => println!("{}月は、夏休みです。", num), 8 => println!("{}月は、お盆休みです。", num), 9 => println!("{}月は、新学期です。", num), 10 => println!("{}月は、ハロウィンです。", num), 11 => println!("{}月は、ブラックフライデーです。", num), 12 => println!("{}月は、クリスマスです。", num), _ => println!("{}月という月はありません。", num) } } [/code] 複数の値を入力できるよう記述も可能 ### loop式 [code] fn main() { let max = 100; let mut ans = 0; let mut count = 1; loop { if count > max { break; } ans += count; count+= 1; } println!("1から{}までの合計は、{}です。", max, ans); } [/code] "+="は代入演算式 ### while式 [code] fn main() { let max = 100; let mut ans = 0; let mut count = 1; while count <= max { ans += count; count+= 1; } println!("1から{}までの合計は、{}です。", max, ans); } [/code] ### for [code] fn main() { let max = 100; let mut ans = 0; for item in 1..=max { ans += item; } println!("1から{}までの合計は、{}です。", max, ans); } [/code] [code] fn main() { let data = [12, 34, 56, 78, 90]; let mut ans = 0; for item in data { ans += item; } println!("データの合計は、{}です。", ans); } [/code]

Rust基礎

### Rustのバージョン確認
$ rustc –version
rustc 1.57.0 (f1edd0429 2021-11-29)

### Rustのアップデート
$ rustup update

### プロジェクトの作成
$ cargo new sammple_rust_app

### Rustの型
主に整数、実数、論理、文字などが用意されている

### 整数型
i8, u8, i16, u16, i32, u32, i64 u64, isize, usize
※符号付き、なしが用意されている。サイズはメモリサイズで、小さい方がメモリを消費しない
※可変はプログラムのプラットフォームの値
特別な理由がなければi32を使用する
浮動小数の型はf32, f64がある。f32は特別な理由がない限り使わない

### 文字
char型: 1文字の型、シングルクォート記号をつける
str型: 一般的なテキスト型、ダブルクォート記号をつける
bool型: true or false
スカラ型(1つの値)とベクター型(動的に値を増減できる)

### 値の演算
– 型の変換はas、テキストの演算は+

### 変数の型指定
let 変数: 型 = 値;

fn main(){
	let x = 100;
	let y:i64 = 200;
	let z = x + y;
	println!("{}+{}={}", x, y, z);
}

“!”はマクロを指す
mutによる可変設定

fn main(){
	let x = 100;
	let y:i64 = 200;
	let mut z = x + y;
	println!("{}+{}={}", x, y, z);
	z = x - y;
	println!("{}-{}={}", x, y, z);
}

変数のシャドーイングという機能を使うと、新たに変数を定義することができる
常に変わらない変数はconstを使って宣言する。rustは定数は大文字で記述する

fn main(){
	const X:i32 = 100;
	const Y:i32 = 200;
	const Z:i32 = X + Y;
	println!("{}+{}={}", X, Y, Z);
}

Reactの環境構築 & AntDesign

$ node –version
v16.13.2
$ npx create-react-app react_app
$ yarn start
http://192.168.56.10:3000/
=> 問題なければstopする

ant designもインストール
$ npm install antd
$ npm audit fix –force

srcディレクトリ内で作業
App.js

function App(){
  return (
      <div className='App'>
        <header className='App-header'>
        </header>
      </div>
    )
}
import {
	BellFilled,
	CaretDownOutlined,
	FormOutlined,
	UserOutlined,
} from '@ant-design/icons/lib/icons';
import { Avatar, Col, Input, Row, Typography } from 'antd';

function App(){
  return (
      <div className='App'>
        <header className='App-header'>
        	<div>
        		<Title>Hpscript</Title>
        		<div>
        			<CaretDownOutlined />
        			<Input placeholder='キーワードを入力' />
        		</div>
        		<div>
        			<div>
        				<FormOutlined />
        				<Text>
        					投稿する
        				</Text>
        			</div>
        			<div>
        				<BellFilled />
        			</div>
        			<Avatar size='large' icon={<UserOutlined />} />
        		</div>
        	</div>
        </header>
      </div>
    );
}

export default App;

src/App.js
Line 14:12: ‘Title’ is not defined react/jsx-no-undef
Line 22:14: ‘Text’ is not defined react/jsx-no-undef

import { Breadcrumb } from 'antd';
import React from 'react';

const App: React.FC = () => (
	<Breadcrumb>
	    <Breadcrumb.Item>Topページ</Breadcrumb.Item>
	    <Breadcrumb.Item>
	      <a href="">ページタイトルA</a>
	    </Breadcrumb.Item>
	    <Breadcrumb.Item>
	      <a href="">ページタイトルB</a>
	    </Breadcrumb.Item>
	    <Breadcrumb.Item>ページタイトルC</Breadcrumb.Item>
	</Breadcrumb>
);

export default App;

Datepicker

import React from 'react';
import { DatePicker } from 'antd';

const App = () => {
	return <DatePicker />;
}

export default App;

First Example

import React from 'react';
import { Button, Space, DatePicker, version } from 'antd';

const App = () => (
	<div style={{padding: '0 24px '}}>
	<h1>antd version: {version}</h1>
	<Space>
		<DatePicker />
		<Button type="primary">Primary Button</Button>
	</Space>
	</div>
)

export default App;

getting start

import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { DatePicker, message } from 'antd';
import './index.css';

const App = () => {
  const [date, setDate] = useState(null);
  const [messageApi, contextHolder] = message.useMessage();
  const handleChange = (value) => {
    messageApi.info(`Selected Date: ${value ? value.format('YYYY-MM-DD') : 'None'}`);
    setDate(value);
  };
  return (
    <div style={{ width: 400, margin: '100px auto' }}>
      <DatePicker onChange={handleChange} />
      <div style={{ marginTop: 16 }}>
        Selected Date: {date ? date.format('YYYY-MM-DD') : 'None'}
      </div>
      {contextHolder}
    </div>
  );
};

createRoot(document.getElementById('root')).render(<App />);
export default App;
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { DatePicker, message, Alert } from 'antd';
import './index.css';

const App = () => {
  const [date, setDate] = useState(null);
  const [messageApi, contextHolder] = message.useMessage();
  const handleChange = (value) => {
    messageApi.info(`Selected Date: ${value ? value.format('YYYY-MM-DD') : 'None'}`);
    setDate(value);
  };
  return (
    <div style={{ width: 400, margin: '100px auto' }}>
      <DatePicker onChange={value => this.handleChange(value)} />
      <div style={{ marginTop: 20 }}>
      	<Alert message="Selected Date" description={date ? date.format('YYYY-MM-DD') : 'None'} />
      </div>
      {contextHolder}
    </div>
  );
};

createRoot(document.getElementById('root')).render(<App />);
export default App;
import { ConfigProvider } from 'antd';
import React from 'react';


const App: React.FC = () => (
	<ConfigProvider theme={{ token: { colorPrimary: '#00b96b'} }}>
		<MyApp />
	</ConfigProvider>
);

export default App;