Meme generator の回 （Scrimbaで学ぶReact）

## 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>
    )
}
```
解説で

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

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

## 条件 (三項) 演算子（Ternary）
[条件 (三項) 演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)

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

//Ternaryに書き換えると

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

## 論理演算子 &&
[実際のコード](https://scrimba.com/scrim/co28742b798b77cff06b48baa)

``` 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の違うものがある時はどのようにしたら良いか？
[実際のコード](https://scrimba.com/scrim/co78d4f2ba20a5eb7a05cde04)
```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ボタンの場合は？
[実際のコード](https://scrimba.com/scrim/co2a44a638dafda56c50f29fd)
nameは同じだけど、valueはそれぞれの文章を挿入。
checked属性も使える。

セレクトボックスの場合は？
[実際のコード](https://scrimba.com/scrim/co4524e4ab64e24f999869eca)
親要素にid属性等を指定。