py-py’s blog

何か書くよ

React Hooksメモ

useStateで初期値およびその値を変更する関数名を定義

import React from "react"
import { useState } from "react"

const App = (props) => {
  
  // 初期値定義
  const states = {
    name: "砂糖",
    price: "100",
  }

  // 状態管理
  // useStateでは戻り値が二つ(初期値と初期値を変更する関数)
  // 変数名と関数変数名はそれぞれ変数名, set変数名とするのが慣習
  // 初期値をname, 関数名をsetNameとする
  const [name, setName] = useState(states.name)

  // priceについても同様
  const [price, setPrice] = useState(states.price)

  // 以下jsxによる描写
  return (
    <React.Fragment>
    <p> 商品: {name} の価格は{price}円です</p>
    </React.Fragment>
    )
  }

export default App

サンプルとしてnameやpriceを変えてみる

import React from "react"
import { useState } from "react"

const App = (props) => {
  
  // 初期値定義
  const states = {
    name: "砂糖",
    price: 100,
  }

  // 状態管理
  // useStateでは戻り値が二つ(初期値と初期値を変更する関数)
  // 変数名と関数変数名はそれぞれ変数名, set変数名とするのが慣習
  // 初期値をname, 関数名をsetNameとする
  const [name, setName] = useState(states.name)

  // priceについても同様
  const [price, setPrice] = useState(states.price)

  // 以下jsxによる描写
  return (
    <React.Fragment>
    <p> 商品: {name} の価格は{price}円です</p>
    <input value={name} onChange={(e) => setName(e.target.value)}/>
    <button onClick={() => setPrice(price + 1)}>+ 1</button>
    <button onClick={() => setPrice(price - 1)}>- 1</button>
    </React.Fragment>
    )
  }

export default App;

onChange={(e) => setName()}のところはonChange=(無名関数と引数(この場合eventを引数としている)を記述している。
これはreactとかじゃなくてjsのほうか。

今だとname, priceともに別々で管理している(別変数で定義している)。
これを一つにまとめるには以下のように書き換える

import React from 'react'
import { useState } from 'react'

const App = (props) => {
  // propsをuseStateの引数に与え、状態を変数stateに集約
  const [state, setState] = useState(props)

  // 集約した状態をそれぞれname, priceと命名
  const { name, price } = state

  // jsxではname, priceとそのまま使うことができる
  return (
    <React.Fragment>
      <p>現在の{name}は、{price}円です</p>
      <button onClick={() => setState({...state, price: price + 1})}> +1</button>
      <button onClick={() => setState({...state, price: price - 1})}> -1</button>
      // 初期値へ戻す
      <button onClick={() => setState(props)}>reset</button>
      // ...の意味についてはコード外を参照
      <input value={name} onChange={(e) => setState({...state, name: e.target.value})}/>
      </React.Fragment>
  )
}
App.defaultProps = {
  name: "サンプル",
  price: 100,
}

export default App;
<input value={name} onChange={(e) => setState({...state, name: e.target.value})}/>

の部分を詳しく。

...stateでオブジェクトを展開し、第二引数で更新したいものをさらに辞書型で定義している。

参考

qiita.com

useEffect

参考

ja.reactjs.org

import React from 'react'
import { useState, useEffect } from 'react'

const App = (props) => {
  const [state, setState] = useState(props)
  const { name, age } = state
  
  // renderが終わった後でuseEffectが実行
  useEffect(() => {
    })

  // 最初のrenderが終わった後限定にしたい場合、useEffectの第二引数に空のリストを渡す
  useEffect(() => {
    }, [])

  // 特定の要素だけが変わった時に実行したい(今回はage)は、第二引数に要素名を書いたリストを渡す
  useEffect(() => {
  }, [age])

  return (
    <React.Fragment>
      <p>現在の{name}は、{age}才です</p>
      <button onClick={() => setState({...state, age: age + 1})}> plus 1 old</button>
      <button onClick={() => setState({...state, age: age - 1})}> minus 1 old</button>
      <input value={name} onChange={(e) => setState({...state, name: e.target.value})}/>
      </React.Fragment>
  )
}
App.defaultProps = {
  name: "tarou",
  age: 12,
}

export default App;

Redux メモ

Reduxはコンポーネントが大きくなった際に状態を管理する

格納先(一例)
src/actions/xxxx.js

  • reducer
    actionが発生した際に、そのactionに組み込まれたタイプに応じて状態をどう変化させるのか定義する

以下をインストールする

npm install redux
npm install react-redux

以下のようなactionを作る。
actions/index.js

export const INCREMENT = 'INCREMENT'
// action関数を設定
export const increment = () => {
    return {
        type: INCREMENT
    }
}

以下のファイルをつくる。これはアプリケーション内でのreducerを管理するファイルとなる
src/reducers/index.js

import { combineReducers } from "redux"; // 結合する関数をインポート
import application_name from "../application_name"

// 一つに管理
export default combineReducers(
  {
    application_name,
  }
)

reducerファイルを作る
src/reducers/application_name.js

// 
import { INCREMENT, DECREMENT} from "../application_name";

// 状態の初期値を設定
const initialState = { value: 0}

export default (state=initialState, action) => {
    // actionのタイプに応じて処理を帰る
    switch (action.type) {
        case INCREMENT:
            return { value: state.value + 1}
        default:
            return state
    }

}

Reactメモ

propsについて、ページ側(親)で各コンポーネント(子)にプロパティなどを渡している

app.js

import React, {Component} from 'react';

const App = () => {
    const profiles = [
        {
            name: "tarou",
            favorite: "game",
            job: "student",
            score: 80,
        },
        {
            name: "hanako",
            favorite: "cooking2,
            job: "no job",
        },
    ]

    return <div>
        {
            profiles.map((profile) => { // 各項目をmap()で回す
                return <User name={ profile.name }  // profileの値をUserコンポーネントへ渡す
                             age={ profile.age }
                             job={ profile.job}
                />
            })
        }
    </div>
}

const User = (props) => { // propsでUserコンポーネントへ渡された値を取得操作する
    return <div>HI! I am {props.name} ! and my favorite is {props.favorite} years old! and my job is {props.job}</div>
}

// 以下の記述でデフォルト設定を設定することが可能
User.defaultProps = {
    age: 1,
    favorite: "no",
    job : "no job",
    score: 80,
}

// 以下の記述でタイプの指定や条件(一種のバリデーション)が設定できる
User.propTypes = {
    name: PropTypes.string, // nameは文字列指定
    score : PropTypes.number.isRequired, // ageは数字型で必ず必要
}

export default App;

stateとは、propsとは違い、各コンポーネントの中でのみ使用する状態のこと。
propsは変更不可能だが、stateは変更可能。

クラスコンポーネントで状態管理
コンポーネントの管理を行うのはsetState({})で行うことができる
また、setState()が実行されるたびにrender()が実行され画面が再描写される。

App.js

import React, {Component} from 'react';

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

class Counter extends Component  {
    // constructorは親の要素を受け取り、それをpropsで扱うことができる
    constructor(props) {
        super(props);
        this.state = {count: 0}
    }

    handlePlusButton = () => {
        // 状態管理を扱う際の関数
        this.setState({count :this.state.count + 1})
    }

    handleMinuxButton = () => {
        this.setState({count: this.state.count - 1})
    }

    render() {
        console.log(this.state)
        return (
            <React.Fragment>
                <div>count: {this.state.count}</div>
                <button onClick={this.handlePlusButton}>+1</button>
                <button onClick={this.handleMinuxButton}>-1</button>
            </React.Fragment>
        )
    }
}

export default App;

Django- imageファイルの格納

Djangoで画像を扱いたいときの対応。

projectとしてportfolioを作成
applicationとしてblogを作成
blog/models.py

from django.db import models

class MyPhotos(models.Model):
    title = models.CharFiled(max_length=20)
    image = models.ImageField(upload_to="blog/images/")

ImageFieldを使う際はpillowが必要なので以下を実行する

pip3 install pillow

blog/admin.py

from django.contrib import admin
from .models import MyPhotos

admin.site.register(MyPhotos)

portfolio/settings.py

~~(略)~~
INSTALLED_APPS = [
    ~~(略)~~
    "blog", # applicationを追加
]

~~(略)~~

MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

portfolio/urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path("admin/", admin.site.urls),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

1 .管理画面からblogアプリケーションを新規登録
2. 画像ファイルをアップロード
3. 該当するファイルをクリック
4. 画像が表示されればOK

管理画面からアップロードした画像ファイルは、rootフォルダ(manage.pyがあるフォルダ)にmediaフォルダへ格納されている