20210430のReactに関する記事は7件です。

スマートコントラクトを使ったサンプルWeb3.0アプリケーションを開発する

solidityを使ったWeb3.0アプリケーションをコーデイングしてみた ネット上でも、solidityを使ったweb3.0アプリケーションを使って開発した本や記事がまだまだ少ないので記事を投稿してみました。 下記書籍を参考に今回は、Web3.0アプリケーションを作ってみました。 実践スマートコントラクト開発 ソースコードは、GitHub上で公開しています。 fundraiser-dapp いきなり、メインネットやテストネットで試すのはハードルが高いため、Ganacheを使って、プライベートネット上にスマートコントラクトを デプロイしてWeb3.0アプリケーションを体感してみました。 なお、このリポジトリを動かすには、事前に下記が必要となります。 node.jsをインストールしておくこと ganacheをインストールして事前に起動しておくこと ganacheを使ってプライベートネット上にスマートコントラクトをデプロイすること 4. MetaMaskをインストールしておくこと プライベートネットの秘密鍵をMetaMaskにインポートしておくこと 以上となります。 まず、コーディングして感じたのが、フレームワーク「truffle」と「React」の凄さ!! Reactはフロントエンド側開発用のJavaScriptのフレームワークとなりますが、JSXを使って、要素をコンポーネントとして扱うところが面白い! ぜひ、習得して実際の業務でも使用してみたいと思いました!! そして、何より、コマンド「truffle unbox react」でテンプレートファイルが作成されて土台部分がすぐに出来上がるのが便利すぎる!! 最初は、何書いてあるかチンプンカンプンだったが、段々と勉強していくうちに分かったので、特に問題なし! MetaMaskと組み合わせて、実際に動かしてみるとブロックチェーンがデータベースの一種であるという説明にも納得がいく。 今までは、本の中に書いてあるだけでなんとなくでしか理解していなかったが、やはり自分でコーディングしてみると理解度にも天と地の差がある。 これで、Web3.0アプリケーションの土台部分ができたわけで、色々と試していきたいと考えている。 EIP712のデモサンプルやマルチシグコントラクトと合わせて、マルチシグウォレットアプリなんかを作ってみると面白いかも。。。 ブロックチェーンエンジニアになりたいと思ってきた!! 今は、コロナ禍で色々と制約があって大変だけど、アフターコロナに備えて自分の技術力をさらに高めていきたいと考えている。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【React】Material-UIで導入したコンポーネントのカラー変更方法

Material-UIの色 Material-UIでボタンやアプリバーなどを手軽に導入できますが、そのまま導入するとデフォルトの色で配置されます。 アプリによってはデフォルトとは違う色合いでコンポーネントを使いたい場合があると思います。 今回はデフォルトから指定の色に、コンポーネントの色を変更する方法について書いていきます。 実装方法 いきなりですが実装方法です。 今回はアプリバーの「基本的な検索フィールド付きApp Bar」を使用します デフォルトは下記画像になります。 基本的に青色を基調とし、数字は赤色になっています。 このコンポーネントのコードに、そのままコンポーネントのcolorをredにしてもコンポーネントの色は変わりません。 コンポーネントの色を変えるには、 1.createMuiThemeを定義して、色を定義する 2.上記で定義したcreateMuiThemeをthemeとして親要素の引数で渡す 上記2点をする必要があります。 下記のようになります。 APP.js import React from 'react'; import PrimarySearchAppBar from "./component/MaterialUIHead"; import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; //primaryとsecondaryで、色を指定します const myTheme = createMuiTheme({ palette: { primary: { main: "#9c27b0", },   secondary: { main: "#76ff03", }, }, }); function App() { return ( //PrimarySearchAppBarの親要素にThemeProviderを配置し、themeに上記で定義したmyThemeを渡します <ThemeProvider theme={myTheme}> <PrimarySearchAppBar></PrimarySearchAppBar> </ThemeProvider> ); } export default App; 上記コードを適用すると、下記のようになります。 今回はPrimaryに紫、secondaryに黄緑色を指定しました。 色について ちなみに、任意の色の16進数を下記で定義できます。 Material-UI Playground https://material-ui.com/ja/customization/color/#playground 参考 Material-UI コンポーネント内のテーマへのアクセス https://material-ui.com/customization/theming/#accessing-the-theme-in-a-component Material-UI基本的な検索フィールド付きApp Bar https://material-ui.com/ja/components/app-bar/#app-bar-with-a-primary-search-field Material-UI Playground https://material-ui.com/ja/customization/color/#playground
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Next.jsセットアップ / TypeScript化 / Material UI導入 / i18n対応までの手順【後編】

Next.jsを使ったサイトのサンプルフォーマットとなるようなものを作りました。 後編ということでnext-i18nextを使った多言語対応の手順について記載します。 (おさらい)作った画面 Material UIのサンプルページを少し加工して ヘッダ部の「こんにちは!こちらは日本語です。」 ボディ部の「サンプルプロジェクト」 以上の2箇所の文言をi18n対応しています。 すぐ横にある「言語を変更」ボタンクリックで英語表記に変えることができます。 前編の記事 Githubリポジトリ i18n対応とは? 国際化対応とも言われる。 ソフトウェアやインターネットサイトを複数の言語で使用、閲覧可能な状態にすること。 「Internationalization」の省略表記で、最初と末尾の文字、及びその間の文字数を記載して「i18n」と呼ぶらしい。 今回はnext-i18nextを使って、サイトを多言語化しましたのでそちらの手順を記載します。 手順説明 next-i18nextのインストール yarn add next-i18next 翻訳ファイルの作成 ページ上の言語変換箇所にKeyを設定します。 そのkeyの参照先となるJSONファイルを各言語ごとに作成します。 今回は日本語及び英語対応としました。 JSONファイルは ./public/locales/[laguage] 配下に、common.jsonの名前で作成します。 mkdir public cd public mkdir locales cd locales mkdir ja cd ja touch common.json ディレクトリ構成はこんな感じです。 . └── public └── locales ├── ja | └── common.json └── en └── common.json common.jsonの作成 JSONファイルはこのように書きます。 common.json(ja) { "hello": "こんにちは!こちらは日本語です。", "change-locale": "言語を変更", "project-name": "サンプルプロジェクト" } 英語版も同じように作ります。 (もちろんですが英語版common.jsonのJSONの各キーの値は英語で記載) next-i18next.config.jsの作成 プロジェクトルートにnext-i18next.config.jsを作成します。 ファイルの中身はこのようにします。 next-i18next.config.js module.exports = { i18n: { defaultLocale: 'ja', locales: ['ja', 'en'], }, } next.config.jsの作成 プロジェクトルートにnext.config.jsファイルを作成します。 ファイルの中身はこのようにします。 next.config.js const { i18n } = require('./next-i18next.config'); module.exports = { i18n, }; appWithTranslationでHOCする _app.tsx内のメインモジュールをappWithTranslationでHOCします。(言い方正しいかな。。。) 具体的にはこのように書きます。 _app.tsx import { appWithTranslation } from 'next-i18next'; const MyApp = ({ Component, pageProps }: AppProps) => { // your Code }; export default appWithTranslation(MyApp); serverSideTranslations、及びキーの追加 index.tsxにおいて、serverSideTranslationsの追加をします。 index.tsx import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations' const Homepage = () => { const router = useRouter() const { t } = useTranslation('common') // your Code } export const getStaticProps = async ({ locale }) => ({ props: { ...await serverSideTranslations(locale, ['common', 'footer']), }, }) export default Homepage 上記サンプルの//your codeの箇所にサイトの具体的表記となるHTMLタグ等の記載があると思いますが、そちらの言語対応したい箇所にcommon.jsonのキーの追加を行います。 index.tsx TypeScript + Next.js + Material UI Sample <div>{t('hello')}</div> 上記の通り、t('keyname')で指定をします。 index.tsx <Typography variant="subtitle1" gutterBottom={true}> {t('project-name')} <Link href='/' locale={router.locale === 'ja' ? 'en' : 'ja'}> <button>{t('change-locale')}</button> </Link> </Typography> 言語変更ボタンはリンクとしていますが、プルダウンなんかの対応もできるかと思います。 起動と動作確認 npm run dev こちらでキーを指定した箇所がうまく切り替わると思います。 参考情報 next-i18nextのREADMEが参考になります。 ぜひお試し頂ければと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

useStateの値が更新されず詰まった話

先日、useStateを使ってとあるstateを更新しようとしたところ、全く意図した挙動にならなかった。 最初はuseStateが原因ではなく他のコードが悪さをしていると思い、書いたコードを片っ端から確認したが結局原因分からず。 ふと、useStateが原因ではないかと思い至って、いじったところ見事エラーが解消しました。 今後同じようなエラーでハマりたくないので、今回は戒めてとして記事を書こうと思います。 ※因みに実際に発生したエラーのコードは複雑になっているので、別例を使って今回のエラーを振り返りたいと思います。 どのようなエラーでハマったのか まずはハマったエラーを簡素的に表そうと思ったのですが、難しかったので一般的に陥りそうな例をあげてみます。 const [currentNum, setCurrentNum] = useState(0) const onHandleClick = () => { setCurrentNum(currentNum + 1) setCurrentNum(currentNum + 1) } イマージ的には上記のような処理をしようとしていたと思ってください。 この時に私の中ではonHandleClickを呼び出したらcurrentNumが2づつ増えていくものだと思っていました。 しかし実際にはonHandleClickを呼び出しても+1にしかなりません。 これはなぜなのか? 一連の処理の流れ 上記で挙げたコードではどうしてcurrentNumが+2にならずに、+1なのか。 それは、この時のcurrentNumには初期値の0が入ってしまっているからです。 具体的にコードで表すと以下のようになっています。 const [currentNum, setCurrentNum] = useState(0) const onHandleClick = () => { setCurrentNum(0+ 1) setCurrentNum(0+ 1) //両方の更新関数には初期値の0が入ってしまっているので、 //このonHandleClick関数内でいくら更新関数を継ぎ足しても1にしかならない //因みにcurrentNumに1が入っていれば2にしかなりません。0というのはあくまでも一例です。 } ではどのようにすれば意図したように+2にづつ増やす事ができるのか? 解決方法 答えは更新関数で値が更新されるのは関数が呼び出された後なので、 更新関数を実行する際に前回の値を渡してあげることです。 こちらも具体的にコードで表すと以下になります。 const [currentNum, setCurrentNum] = useState(0) const onHandleClick = () => { setCurrentNum((currentNum) => currentNum + 1) setCurrentNum((currentNum) => currentNum + 1) //関数で表すことで,コンポーネントのレンダリング走らなくとも引数に前の状態が入って、そこに+1を行っている形になります。 //なので最初の更新関数の引数には初期値の0が入っている状態ですが、 //2回目の更新関数の引数には最初の更新関数で更新された1が入っています。 最後に ふとした瞬間にまた忘れて同じ過ちを繰りかえさないようしにしていきたいものです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React TrackedはContextだけじゃなくてReduxやZustandでも使えるんです

以前react-trackedの紹介と言う記事を書きましたが、その後少しバージョンアップしています。 v1.6.0からは、createTrackedSelectorと言うAPIが追加されReduxなどでも使えるようになりました。そもそもreact-trackedの前身はreactive-react-reduxと言うredux向けのライブラリなので技術的な目新しさはないのですが、react-trackedの位置付けとしてreact contextのためだけのライブラリではないと言うのは実は大きな変化です。 Zustandでも使えますが使い方は同じなのでReduxで説明します。ドキュメントサイトはこちら https://react-tracked.js.org/docs/tutorial-redux-01 使い方は簡単で、まずreact-reduxのuseSelectorをインポートします。 import { useSelector } from 'react-redux'; 次に、react-trackedからcreateTrackedSelectorをインポートします。 import { createTrackedSelector } from 'react-tracked'; 最後に、useTrackedSelectorを作ります。 const useTrackedSelector = createTrackedSelector(useSelector); これにより、 const foo = useSelector(state => state.foo); と書いていたところが、 const { foo } = useTrackedSelector(); と書けるようになります。ただ、これだとあまり嬉しさがわかりませんね。本領発揮するのは、reselectやequalityFnが必要になるケースです。 const selector = state => [state.foo, state.bar]; const [foo, bar] = useSelector(selector); このように書くことはお勧めされていないというか、常にrenderされてしまいます。 const selector = state => [state.foo, state.bar]; const [foo, bar] = selector(useTrackedSelector()); でも、これは大丈夫です。React Trackedのstate usage trackingによって、使われたプロパティが変更された場合だけrenderするためです。 興味がありましたら、GitHubリポジトリやドキュメントサイトを覗いてみてください。 「React Fan」というコミュニティを立ち上げていて、そのSlackでもreact-trackedに関する議論や質問ができますので、よろしければご参加ください。 詳しくは、下記のページをご参照ください。 React開発者向けオンラインサロン「React Fan」の入り口ページ Slackへの招待リンクも上記ページにあります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

時間経過につれて文字がかっこよく遷移するUIを作った件

時間経過につれて文字がかっこよく遷移するUIを作った件 フリーランスでWeb開発を行なっているozoraです。 時間経過につれて文字が遷移していくUIを公開しました。 自分のポートフォリオサイトのトップページでサンプルを公開しています。 自分のサイトでは"Hello there!" -> "こんにちは" -> ... と世界の国の挨拶を順に表示していくように設定しています。 Reactコンポーネントとして実装しているのでReactプロジェクトならどんなサイトでも利用できます。 git clone https://github.com/ozora-ogino/react-text-morpherで簡単に利用できます。 以下で公開していますのでよければ使ってみてください。 (GithubにStarもらえるとozoraは喜びます。)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React で Canvas を使ってお絵描きツールを作る

概要 お絵かきツールを作るための最小の構成を作ったみた。 React + typescript を想定している。 成果物 対象者 React で Canvas を使って最小限のお絵かきツールを作りたい方 動作保証バージョン package.json { "dependencies" { "@types/react": "^17.0.3", "@types/react-dom": "^17.0.3", "react": "^17.0.2", "react-dom": "^17.0.2" } } ブラウザ Chrome 90.0.4430.85 サンプルコード このコードのいいところは余分なものを割と排除しているのでお好みで実装を追加できること。 機能不足の場合は所望の機能を追加くださいませ。 Canvas コンポーネント import React, { useRef } from 'react'; interface IProps { width: number; height: number; } interface IRect { width: number; height: number; left: number; right: number; top: number; bottom: number; } const Canvas: React.FC<IProps> = (props) => { const { width, height } = props let canvasRef = useRef<HTMLCanvasElement | null>(null); let mouseX: number | null = null; let mouseY: number | null = null; const getContext = (): CanvasRenderingContext2D => { const canvas: any = canvasRef.current; return canvas.getContext('2d'); }; const OnClick = (e: React.MouseEvent<HTMLCanvasElement>) => { if (e.button !== 0) { return; } const canvas: any = canvasRef.current; const rect: IRect = canvas.getBoundingClientRect(); const x = ~~(e.clientX - rect.left); const y = ~~(e.clientY - rect.top); Draw(x, y); } const OnMove = (e: React.MouseEvent<HTMLCanvasElement>) => { if (e.buttons !== 1) { return; } const canvas: any = canvasRef.current; const rect: IRect = canvas.getBoundingClientRect(); const x = ~~(e.clientX - rect.left); const y = ~~(e.clientY - rect.top); Draw(x, y); } const DrawEnd = (e: React.MouseEvent<HTMLCanvasElement>) => { mouseX = null; mouseY = null; } const Draw = (x: number, y: number) => { const ctx = getContext(); ctx.beginPath(); ctx.globalAlpha = 1.0; if (mouseX === null || mouseY === null) { ctx.moveTo(x, y); } else { ctx.moveTo(mouseX, mouseY); } ctx.lineTo(x, y); ctx.lineCap = "round"; ctx.lineWidth = 10; ctx.strokeStyle= "#000000"; ctx.stroke(); mouseX = x; mouseY = y; } const Reset = () => { const ctx = getContext(); ctx.clearRect(0, 0, width, height); } return ( <section> <div> <canvas onMouseDown={OnClick} onMouseMove={OnMove} onMouseUp={DrawEnd} onMouseOut={DrawEnd} ref={canvasRef} width={`${width}px`} height={`${height}px`} /> </div> <div> <button onClick={Reset}>リセット</button> </div> </section> ); } export default Canvas; 呼び出す側 import './Canvas'; const App = () => { return <Canvas width={800} height={600} /> } 余談 個人的には謎解きキットの一部として実装したものなので、 canvas に background-image の css を付与して以下のように利用している。 ツイート この記事で一人でも多くのエンジニアが車輪の再発明をすることなく、手早くやりたいことを実現できますように?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む