0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Meme generator の回 (Scrimbaで学ぶReact)

Posted at

Reactでのイベント処理

https://legacy.reactjs.org/docs/events.html
例えば...クリックした時にイベントを発生させたい場合には、onClickを使用する。

ランダムにurlを表示させたい場合

memesData.js
export default {
    "success": true,
    "data": {
        "memes": [
            {
                "id": "181913649",
                "name": "Drake Hotline Bling",
                "url": "https://i.imgflip.com/30b1gx.jpg",
                "width": 1200,
                "height": 1200,
                "box_count": 2
            },
            {
                "id": "87743020",
                "name": "Two Buttons",
                "url": "https://i.imgflip.com/1g8my4.jpg",
                "width": 600,
                "height": 908,
                "box_count": 3
            }]
Meme.jsx
import memesData from "../memesData.js"

export default function meme() {

    function handleClick() {
            const memes = memesData.data.memes //memesDataから個々のmemesキーの値を取得
            const random = Math.floor(Math.random() * memes.length) //ランダム設定
            const randomMeme = memes[random].url //urlキーにランダムにアクセス
            console.log(randomMeme)
    }
    return (
    <button 
         onClick={handleClick}
         className="form--button"
    >
    Get a new meme image 🖼
    </button>
    )
}

コールバック関数でstateを変更する

+ボタンを押すと、1増える。-ボタンを押すと、1減る。
というものを作りました。

App.jsx
import React from "react"

export default function App() {
    const [count, setCount] = React.useState(0)
    
    function add() {
        setCount(count + 1)
    }
    
    function subtract() {
        setCount(count - 1)
    }
    
    return (
        <div className="counter">
            <button className="counter--minus" onClick={subtract}></button>
            <div className="counter--count">
                <h1>{count}</h1>
            </div>
            <button className="counter--plus" onClick={add}>+</button>
        </div>
    )
}

解説で

もし、新しい状態の値を決定する際に、以前の状態の値が必要な場合、stateの値を直接使用する代わりに、stateの設定関数にコールバック関数を渡すべきです。このコールバック関数は、以前の状態の値がパラメータとして渡されるため、それを使用して新しい状態の値を決定することができます。

とありました。
ReactのuseStateフックは、以前の状態の値を正確に保証することができないのですね...
ということで書き直し。

App.jsx
function add() {
        setCount(prevCount => prevCount + 1)
    }

条件 (三項) 演算子(Ternary)

条件 (三項) 演算子

App.js
let answer  // Use ternary here
    if(isGoingOut === true) {
        answer = "Yes"
    } else {
        answer = "No"
    }

//Ternaryに書き換えると

let answer = isGoingOut ? "Yes" : "No"

論理演算子 &&

実際のコード

Joke.jsx
   /**
     * Challenge:
     * - Only display the punchline paragraph if `isShown` is true
   */

//最初は下記のように書いたけど
{isShown ? <p>{props.punchline}</p> : ""}

//tureの時にだけ走ってくれれば良いので、&&を使う
{isShown && <p>{props.punchline}</p>}

React Hooks Formでの気付き

First NameとLast Nameの2つのインプットから値を取得したい。

Form.jsx
export default function Form() {
    const [firstName, setFirstName] = React.useState("")
    const [lastName, setLastName] = React.useState("")
    
    function handleFirstNameChange(event) {
        setFirstName(event.target.value)
    }
    
    function handleLastNameChange(event) {
        setLastName(event.target.value)
    }
    
    console.log(firstName, lastName)
    
    return (
        <form>
            <input
                type="text"
                placeholder="First Name"
                onChange={handleFirstNameChange}
            />
            <input
                type="text"
                placeholder="Last Name"
                onChange={handleLastNameChange}
            />
        </form>
    )
}

というふうに書いていたが、同じことを繰り返していて、よくないのでは...?と思ったら、次のレッスンでそれを避けるための説明をしていた。

From.jsx
export default function Form() {
    const [formData, setFormData] = React.useState(
        {firstName: "", lastName: ""}
    )
    
    console.log(formData)
    
    function handleChange(event) {
        setFormData(prevFormData => {
            return {
                ...prevFormData,
                [event.target.name]: event.target.value
            }
        })
    }
    
    return (
        <form>
            <input
                type="text"
                placeholder="First Name"
                onChange={handleChange}
                name="firstName"
            />
            <input
                type="text"
                placeholder="Last Name"
                onChange={handleChange}
                name="lastName"
            />
        </form>
    )
}

きれいになった...!

typeの違うものがある時はどのようにしたら良いか?
実際のコード

Form.jsx
function handleChange(event) {
        const {name, value, type, checked} = event.target
        setFormData(prevFormData => {
            return {
                ...prevFormData,
                [name]: type === "checkbox" ? checked : value
            }
        })
    }
const {name, value, type, checked} = event.target

これをすると、nameはevent.target.nameになるし、valueはevent.target.valueになる。便利...

Radioボタンの場合は?
実際のコード
nameは同じだけど、valueはそれぞれの文章を挿入。
checked属性も使える。

セレクトボックスの場合は?
実際のコード
親要素にid属性等を指定。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?