はしばみあきら blog

プログラミングアウトプットするブログ。202010スタート

【Rails】【Ruby】Dateを使って今月の日数を配列にして表示

Railsでアプリを作っていて、今カレンダーのような機能を作るフェーズです。
色々とgemとかライブラリを探してみたけど自分の求めているものが見つからない。
自作することにしました。

Dateを使って今月の日数を配列にする

RailsはそもそもRubyなのでRubyの構文使ってバンバン書いていきます。

Dateを使っていきます。DateはRubyの時間や曜日を色々扱えるものです。

このあたりの記事がとてもわかりやすいです。
RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い

まずは現在の時間を出します

コントローラの中で記述しています。

Date.current

ターミナルだとこんな感じで

[3] pry(#<WorkdaysController>)> Date.current
=> Wed, 16 Dec 2020

次に今月の始めを出します。

Date.current に beginning_of_month をつけることで今月の最初の日を取得できます。

Date.current.beginning_of_month
[5] pry(#<WorkdaysController>)> Date.current.beginning_of_month
=> Tue, 01 Dec 2020

次に配列を作ります。1ヶ月は大体30日ですが、前後2~3日まで表示することを考えて35日分の表示になるよう配列を作ります。

Array.new(35){|i|i}

Array.newで配列の新規作成、(35)は配列の中身の数です。{ |i| i } とすることで i が1ずつ増えながら配列を作ることができます。

[6] pry(#<WorkdaysController>)> Array.new(35){|i|i}
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]

次に wday というものを使います。これは、その日の曜日を数字に変換するものです。
["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]の順で、0,1,2,3,4,5,6で入ります。

Date.current.beginning_of_month.wday
[2] pry(#<WorkdaysController>)> Date.current.wday
=> 3

今日(2020/12/16)は水曜日なので、配列の4番目に当たる水曜日が数字で返されます。
4番目なので、0から数えて3になります。

今月初めの日の曜日を取得します。

Date.current.beginning_of_month.wday
[9] pry(#<WorkdaysController>)> Date.current.beginning_of_month.wday
=> 2

35の配列から、この数字を引いた日をスタートとします。

Array.new(35){|i|i - Date.current.beginning_of_month.wday}
[10] pry(#<WorkdaysController>)> Array.new(35){|i|i - Date.current.beginning_of_month.wday}
=> [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

今月と、前後数日が入る配列ができたので、ここに日付として入れるようにしていきます。

Array.new(35){ |i| Date.current.beginning_of_month + ( i -  Date.current.beginning_of_month.wday)}
[13] pry(#<WorkdaysController>)> Array.new(35){ |i| Date.current.beginning_of_month + ( i -  Date.current.beginning_of_month.wday)}
=> [Sun, 29 Nov 2020,
 Mon, 30 Nov 2020,
 Tue, 01 Dec 2020,
 Wed, 02 Dec 2020,
 Thu, 03 Dec 2020,
 Fri, 04 Dec 2020,
 Sat, 05 Dec 2020,
 Sun, 06 Dec 2020,
 Mon, 07 Dec 2020,
 Tue, 08 Dec 2020,
 Wed, 09 Dec 2020,
 Thu, 10 Dec 2020,
 Fri, 11 Dec 2020,
 Sat, 12 Dec 2020,
 Sun, 13 Dec 2020,
 Mon, 14 Dec 2020,
 Tue, 15 Dec 2020,
 Wed, 16 Dec 2020,
 Thu, 17 Dec 2020,
 Fri, 18 Dec 2020,
 Sat, 19 Dec 2020,
:

コードがものすごく長くなってしまいました。
ここまでを変数に代入しながらまとめます。

  def month

    # 現在の曜日と年月日
    date_now = Date.current

    firstDay = date_now.beginning_of_month
    firstDayIndex = firstDay.wday
    @calender = Array.new(35){|i| firstDay (i - firstDayIndex)}
  end

この変数をview側に渡してやります ちなみにslimとbootstrapを導入しています

h1 月間表

p = @month_now

table.table.table-bordered
  thead
    tr
      th 月日
      - @calender.each do |c|
       td = "#{c.month}/#{c.day}"

f:id:hashibamiakira:20201216214851p:plain

前月末からの表示ができました。

次に曜日を足します。
コントローラに少し足します。

  def month
    # 現在の曜日と年月日
    date_now = Date.current

    @weeks = ["", "", "", "", "", "", ""]

    firstDay = date_now.beginning_of_month
    firstDayIndex = firstDay.wday
    @calender = Array.new(35){|i| firstDay + (i - firstDayIndex)}
  end

@weeksに曜日を文字として入れる配列を作りました

これをviewに渡して、曜日を表示させます

h1 月間表

p = @month_now

table.table.table-bordered
  thead
    tr
      th 月日
      - @calender.each do |c|
       td = "#{c.month}/#{c.day}"

  thead
    tr
      th 曜日
      - @calender.each do |c|
        td = @weeks[c.wday]

f:id:hashibamiakira:20201216215249p:plain

@calenderの配列を回して、@weeksの配列の番号と、cに代入された日のwdayで探します。

これで1ヶ月分の表示ができました

またボチボチ更新していきます。

【React】Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

reactで開発中以下のエラーが。

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

最近はとりあえず翻訳してみてます。

f:id:hashibamiakira:20201215192939p:plain

なるほど、でもどこがレンダリングがループし続けているかがわからない...

エラー文で調べたら記事がありました。本当に助かりました。

【意外とハマる??】Reactで、無限ループに気をつけましょう

今回の自分のコードはここが問題だった

      <IconButton
        size="small"
        onClick={
          dispatch({type: 'decrement'}),
          setPreviousMonth
        }
      >
        <ArrowBackIos />
      </IconButton>
      <IconButton
        size="small"
        onClick={
          dispatch({type: 'increment'}),
          setPreviousMonth
        }
      >

onClickでdispatchを送りstateを変更するように記述。

しかしこの記述だとまず画面が読み込まれた瞬間(レンダリングされた瞬間)にdispatchが動いてしまうみたいです。

なのでstateが変更

stateが変更されればレンダリングするというルールなのでまた読み込み

そしてdispatchが送られる...という無限ループが発生していたようです。

そしてこれはアロー関数で防げるみたい。

      <IconButton
        size="small"
        onClick={
          () => dispatch({type: 'decrement'}),
          setPreviousMonth
        }
      >
        <ArrowBackIos />
      </IconButton>
      <IconButton
        size="small"
        onClick={
          () => dispatch({type: 'increment'}),
          setPreviousMonth
        }
      >

エラーは消えた!絶対これからも出てくるエラーだから覚えておかねば。

...と思ったらonClickが動きません。onClickの書き方がまずそうだ。

とりあえずエラーは解決。またボチボチ更新していきます。

フロントReact、バックRailsでデータベースに保存する

最近Reactを色々やってみて、ふと「DBに保存するにはどうすれば良いのだろう?」と言う疑問が沸き調べたところReact単体でDBに保存するのはできないと言うことがわかりました。

ReactとはNode.jsとつなげた方がJS同士だからいいんだろうけど、慣れているRailsをバックにしてみます。

調べたことをアウトプットしながら書いていくのでコードだけ欲しい!みたいな人には冗長に感じるかもですがご愛敬。

RailsAPIとして使う

同じ初学者の人だとそもそも「RailsAPIで使うってどう言うこっちゃ?」ってなると思います。
自分もなりました。

Javascriptの入門本とかだとポピュラーなのはウェザーAPIだし
有名どころで言えばGoogleAPIとかYoutubeAPIとかですね。

そもそもAPIってなんぞ?と言うことです
以下のようなことらしいです

API」とは、「Application Programming Interface」の頭文字です。

英文字だけで意味を理解しようとすると、アプリケーション・プログラミング・インターフェイスで、大雑把に言うと「アプリケーションをプログラミングするためのインターフェース」という意味です。

インターフェイスとは、コンピュータ用語でいうと、「何か」と「何か」をつなぐものという意味を持ちます。例えば、USBも「パソコン」と「周辺機器」をつなぐものですので、インターフェイスの一つです。

つまり、APIとは、この「何か」と「何か」が「アプリケーション、ソフトウェア」と「プラグラム」をつなぐもの、という意味になります。

今さら聞けないIT用語:やたらと耳にするけど「API」って何?

つまりRailsでフロントとサーバーを繋ごうと言うことになるのかな

viewは完全にReactで作り、Railsにデータを渡してそこからDBにと言う感じですね

実際に作っていきます

RailsAPIとして作る

こちらが大変参考になりました
Ruby on Rails+ReactでCRUDを実装してみた

この記事を参考に進めます

まずはrails newです
お世話になっているRailsガイドに書いてあります
Rails による API 専用アプリケーション

API専用Railsアプリケーションの生成には次のコマンドを使います。

$ rails new my_api --api

--api をオプションでつけることでRailsAPI専用で作成できます

作られたアプリに移動したらモデルを作ります

$ rails g model user name:string

$ rails db:migrate

DBのデータがやりとりできるか確かめるためにテストデータを作成します

User.create([
  {name: "鈴木"},
  {name: "田中"},
  {name: "佐藤"}
  ])
rails db:seed

コントローラを作成

$ rails g controller users
class UsersController < ApplicationController

  def index
    @users = User.all
    render json: @users
  end

  def create
    @user = User.create(name: params[:name])
    render json: @user
  end

  def update
    @user = User.find(params[:id])
    @user.update(name: params[:name])
    render json: @user
  end

  def destroy
    @user = User.find(params[:id])
    if @user.destroy
      head :no_content, status: :ok
      # headメソッド...本文(body)のないレスポンスをブラウザに送信できる
      # :no_content...レンダリングしようとすると、レスポンスから削除される
      # status: :ok...リクエストに成功
    else
      render json: @user.errors, stateus: :unprocessable_entity
      # stateus: :unprocessable_entity...バリデーションエラー
    end
  end
end

render json: オブジェクト とすることでjson形式でオブジェクトが返されます

個人的によくわからない所はコメントをつけてあります

次にルーティングを追加

Rails.application.routes.draw do
  resources :users
end

ここまでできたらRailsのポートを立ち上げてデータがjson形式で帰ってくるか確かめます

Reactで3000番ポート、Railsで3001番ポートを使うので、3001番で立ち上げます

$ rails s -p 3001

立ち上げた状態でもう一つターミナルを立ち上げてアクセスします

$ curl -G http://localhost:3001/products/
[{"id":1,"name":"鈴木","created_at":"2020-12-08T10:07:40.549Z","updated_at":"2020-12-08T10:07:40.549Z"},{"id":2,"name":"田中","created_at":"2020-12-08T10:07:40.553Z","updated_at":"2020-12-08T10:07:40.553Z"},{"id":3,"name":"佐藤","created_at":"2020-12-08T10:07:40.556Z","updated_at":"2020-12-08T10:07:40.556Z"}]

このように、ターミナルにデータが帰ってくれば成功です

しかしここで1つ問題があります
Reactで3000番ポート、Railsで3001番ポートを使う、と言うことにしました
現状、ポートの番号が違う方にアクセスしようとするとエラーがでます

APIとしてデータをやりとりしようとするRailsが、React側の3000番にアクセスできるようにします

gem 'rack-cors'を使います

こちらが参考になりました
【Rails6】Gem rack-corsを導入してCORS設定を行う(オリジン・CORSとは何か)

このgemはrailsに元々コメントとして入っているので、外して導入しましょう

gem 'rack-cors'
$ bundle install

cofig/initializers に cors.rb と言うファイルができますが、config/application で内容を記述します

module TestApp
  class Application < Rails::Application
    
    config.load_defaults 5.2
    config.api_only = true

    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins 'http://localhost:3000'
        resource '*',
        :headers => :any,
        :methods => [:get, :post, :patch, :delete, :options]
      end
    end
  end
end

Rails側の設定ができました

React側を作る

すでにnodeが導入されていればnpmのcreat-react-appを導入します

nodeが入っていない場合はまずnodeを導入しましょう
(検索すると色々でてきます。自分はprogateですでに入れてました)

$ npm i -g create-react-app

今回一枚ものでviewを作るのでfrontと言う名前でreactを構築します

$ create-react-app front

作ったfrontに移動してnpm startでReactが起動します

いきなりブラウザにでてくるかと思います

この時点でアドレスはhttp://localhost:3000/
http://localhost:3001/にすると、起動させていればRailsが開けます

非同期のHTTP通信を簡単にする axios と言うものを導入します
APIとDBのやりとりを簡単に実装できるものらしいです

$ npm i axios

次にApp.jsを変更してメインとなるページを作ります

import React from 'react';

import MainContainer from './Components/MainContainer';

import './App.css';

const App =()=> {
  return(
    <div>
      <MainContainer />
    </div>
  )
}

export default App;

src以下にComponentsディレクトリを作成し、MainContainer.jsxを作成します

import React from 'react';

import axios from 'axios';

class MainContainer extends React.Component {

  state = {
    users: []
  }

  // componentDidMount() は、コンポーネントがマウントされた(ツリーに挿入された)直後に呼び出されます
  // DOM ノードを必要とする初期化はここで行われるべきです
  componentDidMount() {
    axios
      .get('http://localhost:3001/users')
      .then((results) => {
        console.log(results)
        this.setState({users: results.data})
      })
  }

  render(){
    return(
      <div></div>
    )
  }
}

export default MainContainer;

axiosを使って、usersのページをgetします

このusersはindexにあたるので、usersコントローラーのindexからデータが送られてきます
送られてきたjsonは (results) に入り、 this.setState({users: results.data}) で state で管理できるようになります

railsを立ち上げてreactも立ち上げると、真っ白の画面が表示されますが、choromeのデベロッパーツールでconsoleを開くと3件のデータが表示されます

$ rails s -p 3001
(frontに移動して)
$ npm start

f:id:hashibamiakira:20201209010228p:plain

このデータを実際に表示させます

Componentsディレクトリに、

UserContainer.jsx
ViewProduct.jsx

この2つのファイルを作ります

UserContainerは追加したデータをまとめるもの

ViewProductは1つ1つの単体データ

と言った感じです

import React from 'react';
import ViewProduct from './ViewProduct';

const UserContainer = props => {

  return(
    <div>
      { props.userData.map((data) => {
        return(
          <ViewProduct data={ data } key={ data.id } />
        )
      })}
    </div>
  )
}

export default UserContainer;

コンポーネントから渡ってきたpropsを、mapで1つ1つ渡して返してもらいます

import React from 'react';

const ViewProduct = props => {

  return(
    <div>
      <span>{ props.data.name }</span>
    </div>
  )
}

export default ViewProduct;

コンポーネントのMainContaineにはUserContainerを追加して、stateの値を渡すようにします

  render(){
    return(
      <div className="App">
        <UserContainer userData={ this.state.users }/>
      </div>
    )
  }

reduxを使うとまた別ですがstateだけの管理なのでスーパーバケツリレーですね

これでブラウザにはデータ(ユーザーの名前)が表示されていると思います

f:id:hashibamiakira:20201209014127p:plain

表示はできたので、ユーザーを追加するフォームを作ります

まずはmaterial-uiと言うもの導入します

これは簡単に言うと、bootstrapのようなもので、タグに名前をつけることで簡単に装飾ができるものです
(最近知ったので使ってみたかった)

公式はこちらです MATERIAL-UI

npmで導入します

$ npm i @material-ui/core

導入できたらフォーム部分を作ります

ComponentsディレクトリにFormContainer.jsxを作ります

import React from 'react';

import {
  FormGroup,
  FormControl,
  OutlinedInput,
  Button
} from '@material-ui/core'

class FormContainer extends React.Component {

  state = {
    user: ''
  }

  render(){
    return(
      <div>
          <FormGroup>
            <FormControl>
              <OutlinedInput
                type="text"
                value={ this.state.user }
                style={{width: 300, margin: "0 auto"}}
              />
            </FormControl>
          </FormGroup>
        <Button
          type="submit"
          onClick={ this.handleSubmit }
          variant="outlined"
          color="primary"
        >
          追加
        </Button>
      </div>
    )
  }
}

export default FormContainer;

フォームの内容をMainContainer.jsxに加えます

  render(){
    return(
      <div className="App">
        <FormContainer />
        <UserContainer userData={ this.state.users }/>
      </div>
    )
  }

フォームができました、が、入力をしても何も文字は表示されずボタンを押しても何も動きません

onChangeを使ってstateを変更して文字を表示させます

import React from 'react';

import {
  FormGroup,
  FormControl,
  OutlinedInput,
  Button
} from '@material-ui/core'

class FormContainer extends React.Component {

  state = {
    user: ''
  }

  onChangeText = (e) => {
    this.setState({user: e.target.value})
  }

  render(){
    return(
      <div>
          <FormGroup>
            <FormControl>
              <OutlinedInput
                type="text"
                value={ this.state.user }
                style={{width: 300, margin: "0 auto"}}
                onChange={ this.onChangeText }
              />
            </FormControl>
          </FormGroup>
        <Button
          type="submit"
          onClick={ this.handleSubmit }
          variant="outlined"
          color="primary"
        >
          追加
        </Button>
      </div>
    )
  }
}

export default FormContainer;

onChangeTextを作り、フォームの中で呼び出しstateを変化させ、valueに反映しています

それでは追加ボタンでDBに保存できるようにしていきます

まず react-addon-update と言うものを導入します

$ npm i react-addons-update

FormContanierの内容をUserContainerに反映させるので、2つの親コンポーネントRailsとやりとりする記述を追加します

と言うことで、MainContainerに追加していきます

import update from 'react-addons-update'; <=追加

class MainContainer extends React.Component {

  // ---省略---

  createUser = (name) => {
    axios
      .post('http://localhost:3001/users', { name: name })
      .then((response) => {
        const newData = update(this.state.users, { $push: [response.data] })
        this.setState({ users: newData })
      })
  }

  render(){
    return(
      <div className="App">
        <FormContainer createUser={ this.createUser } />
        <UserContainer userData={ this.state.users }/>
      </div>
    )
  }

ここで作成した createUser を FormContainer で呼び出します

class FormContainer extends React.Component {

// ---省略---

  handleSubmit = () => {
    this.props.createUser( this.state.user )
    this.setState({ user: '' })
  }

createUser に対する引数 name にはフォームで入力された文字が返ります

postメソッドなので、users_controller.rbのcreateに(name: params[:name])が返ります

(response) には作られたユーザーのデータが入るので、stateのusersにそのデータを挿入してからstateの更新を行っています

stateが更新されるのでviewはレンダリングされて即座に追加したユーザーが表示されます

コンソールを確認し、ユーザーのレコードが作成されていたら完成です

f:id:hashibamiakira:20201209030412p:plain

これで、ReactからRailsにデータを渡し、DBに保存することができました

1個1個動きを確認しながら記事を作成していたら5時間くらいかかってしまった...

削除や更新も覚えねば!またまとめていきます

【Rails】【MySQL】rails newでDBをmysqlで始める流れ

しばしブログ更新が開きました
最近Reactばかり触って更新するネタがなかったと言う...

Reactのバック側処理としてRailsを使うため、久しぶりにRalisを触ったら沼ったので書き留めておきます

rails newでDBをmysqlで始める流れ

  • Homebrew導入
  • MySQL導入
  • Rails new でDBにMySQLを設定
  • database.ymlに必要な情報を記述

導入している部分は適所飛ばしてください

MySQLを導入

HomebrewでMySQLを導入しますが、RailsをしていればHomebrewは導入してあると思うので、ここは省きます

MySQLの導入はこちらが参考になるかと思います
Mac へ MySQL を Homebrew でインストールする手順

MySQLでは、ユーザー名とパスワードでDB群にアクセスできるみたいです(調べてはいないので変なこと言ってたらすみません)

% mysql -u root -p

-uはユーザー名の指定、-pはパスワードの指定です

最初はおそらくユーザー名はrootになっているはずなので、ユーザー名はroot

パスワードを求められるので設定したものを入力しましょう

ターミナルに色々でてきて、表示が mysql> になっていればOKです

f:id:hashibamiakira:20201206225131p:plain

まずはデータベースがあるか確認します

mysql> show databases;

作ったばかりだとおそらく4つしかないかと思います

最初からあるDBは重要なものなので消さないようにしましょう

自分の場合はこんな感じです

f:id:hashibamiakira:20201206225746p:plain

DBを作成します

mysql> create database 名前;

名前には作ろうとするアプリの名前などを入れておくとわかりやすくていいかと思います

DBができたらRailsでアプリを作ります

Rails new でMySQLを設定

アプリケーションを作るディレクトリでrails newを行います

$ rails new 名前 -d mysql

-d はデータベースの指定です
mysqlとすることで、DBはそれを使う設定で作られます

必要な情報を記述していく

テキストエディタでconfig/database.ymlを開きます

defaultはmysql2を使うようになっているかと思います

defaultのusernameはroot(もし任意の名前にしてあるのであればそちら)にして、passwordは設定したパスワードを入力しておきます

今回開発環境(development)とtestでDBを使うので、この2つのdatabaseの名前を、mysqlで作ったDBの名前にします

自分はreactとrailsを組み合わせるテストをするために、react-railsと言う名前のDBを作ってあります

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: localhost

development:
  <<: *default
  database: react-rails

test:
  <<: *default
  database: react-rails

もしもGithubにpushするなら

開発段階で第三者に見られてもOKならこれでいいですが、本番環境では悪意のあるユーザーから不正にアクセスされるかもしれません

DBの情報(ユーザーネームやパスワード)は隠しファイルにしておいた方が良いです
(隠しファイルにしておいた方が良いものをそのままgitに上げると確認のメールが来るらしい)

環境変数についてはこちらがわかりやすいです
【Rails】dotenv-railsの導入方法と使い方を理解して環境変数を管理しよう!

今回はrailsのDBをMySQLで始める方法で沼ったので書き残しておきます

またボチボチ更新していきます

【MySQL】 rootユーザーのパスワード設定で Error: Password hash should be a 41-digit hexadecimal number が出た

progateでMySQLを導入しようとした時に何やらエラーが出ました

Please set the password for root here.

New password: 

Re-enter new password: 
 ... Failed! Error: Password hash should be a 41-digit hexadecimal number

パスワード設定しようとしたらエラー?入力が間違っているわけでもなく。

エラー文を翻訳

"失敗しました!エラー:パスワードハッシュは41桁の16進数である必要があります"

入力したものをハッシュに変換するのだろうけどなぜかうまく行かない様子。

ルートユーザーのパスワードを別角度から登録しました。
こちらの記事が参考になりました↓
MySQLのrootパスワードを設定 - Linux環境

# mysql -u root

mysql> update mysql.user set password=password('root用の任意パスワード') where user = 'root';
mysql> flush privileges; ← 変更を反映
mysql> exit;

ルートユーザーのパスワードが設定できます。

設定を入力する画面へ。

% mysql_secure_installation
Securing the MySQL server deployment.

Enter password for user root: 

VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No: 
Using existing password for root.
Change the password for root ? ((Press y|Y for Yes, any other key for No) : 

 ... skipping.

新しいパスワードを入れて下さいからパスワードを変更しますか?に変わりました

これでMySQLのパスワードが設定されました。よかったよかった。

【React】Reactを始める手順

ReactとNode.jsを掛け合わせようとして動かなくなる事件が発生した
サラにしてもう一度インストールしたので手順をまとめておくことにします

Homebrewのインストール

  • nodebrewをインストールするために導入
$ cd ~
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew -v

Homebrew が表示されればOK

nodebrewのインストール

$ brew install nodebrew
$ nodebrew -v

nodebrew が表示されればOK

Node.jsのインストール

  • 安定版を取得
$ nodebrew install-binary stable

この時インストールされたバージョンを適用する

$ nodebrew use vバージョン番号

環境パスを通す

ターミナルbashの場合

$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile

ターミナルzshの場合

$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zprofile

ターミナルを一度再起動

npmのインストール

npmがあるか、もしくは最新かを確認

$ npm --version

6未満なら最新版に

$ npm install npm -g

プロジェクトの作成

pmのパッケージ(create-react-app)を導入し使用

$ npm install -g create-react-app
$ reate-react-app アプリ名

これでreactの環境は構築できるはずです。

【React】public以下に画像を保存して、表示させる

Reactで画像を表示させる時どうすればいいんだろう?
と、検索したらジャストナウの答えがすぐ見つかりました。感謝の日々です...

参考サイト

React で publicフォルダ内の静的ファイル(画像)を参照する方法

表示方法

publicのパスは

{`${process.env.PUBLIC_URL}/ ファイル名 `}

これで辿れるみたいです

試しに create-react-app で元々保存されているアイコンを表示してみます

 render(props) {
   return (
     <div className="App">
       <header className="App-header">
         <img src={logo} className="App-logo" alt="logo" />
         <h1 className="App-title">Hello {this.state.text}</h1>
         <span onClick={()=>{this.handleClick("World")}}>world</span>
         <span onClick={()=>{this.handleClick("React")}}>react</span>

        {/* この部分 */}
       <Image image={`${process.env.PUBLIC_URL}/logo192.png`}/>
       </header>
     </div>
   );
 }

ブラウザは以下のように

f:id:hashibamiakira:20201123115319p:plain

アイコンが表示された!
HTMLだとimgタグでパスの指定してあげるだけなんだけど、別の言語でそれができると感動を覚えます

ではpublicにimageフォルダを作り指定してみます

App.js Image.js 画像ファイルはこんな感じ

f:id:hashibamiakira:20201123115928p:plain

で、保存すると

f:id:hashibamiakira:20201123120020p:plain

思ったよりでかい!でも表示することに成功しました

画像の表示はこんな感じです。思ったより簡単

また更新していきます