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でオブジェクトを展開し、第二引数で更新したいものをさらに辞書型で定義している。
参考
useEffect
参考
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はコンポーネントが大きくなった際に状態を管理する
- action
コンポーネントの関数をまとめる
格納先(一例)
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フォルダへ格納されている