Reactで親コンポーネントのstateを下位のコンポーネントのイベント処理で更新する

# React で親コンポーネントの state を下位のコンポーネントのイベント処理で更新する

## 概要
　親コンポーネントで state を管理しているが、input 要素などの子コンポーネント側でイベント処理を行いたい時があると思います。結論から言うと、この場合の解決策の1つとしては、**「親コンポーネントから props 経由でハンドラー関数を渡す」**というやり方があります。気づけばカンタンなことですが、自分はハマってしまったので、誰かの参考になればと思って投稿しました。なお、React 初心者のため、もっと良い解決策がありましたら、ご教授ください。

## 本題

#### 親コンポーネント `Parent`

```jsx:Parent.js
import React, { useState } from 'react';
import Child from './Child.js';

function Parent() {
  // hook's state administration
  const [inputText, setInputText] = useState("");
  // handler function
  function handleInputTextChange(text) {
    setInputText(text);
  }

  return (
    <div className="App">
      <div className="Searcher">
        //!important->
        <Child handleInputTextChange={e => handleInputTextChange(e)}/>
        //<-!imoprtant
      </div>
      // display 'inputText' contents
      <p>{inputText}</p>
    </div>
  );
}
```

### 子コンポーネント `Child`

```jsx:Child.js
import React from 'react';
import Paper from '@material-ui/core/Paper';
import InputBase from '@material-ui/core/InputBase';
import SearchIcon from '@material-ui/icons/Search';
import IconButton from '@material-ui/core/IconButton';

function Child() {
  return (
    <Paper component="form">
      <InputBase
        //!important->
        onChange={(e) => props.handleInputTextChange(e.target.value)}
        //<-!imoprtant
      />
      <IconButton type="submit">
        <SearchIcon />
      </IconButton>
    </Paper>
  );
}

export default Child;
```

　親コンポーネント `Parent` と子コンポーネント `Child` を示しました。

　今回の例では、`Child` にテキスト入力部分 `InputeBase` があり、そのテキスト入力の state を `inputText` という変数で、`Parent` において保持します。テキストの変化は、 `handleInputTextChange` というハンドラー関数で制御します。そして、 `Parent` で `inputText` の内容を表示しています。挙動は以下のようになります。

## ポイント
　今回の解説のポイントは、**「親コンポーネントからprops経由でハンドラー関数を渡す」**ことです。注意すべき点は以下の2点です。

1. `Parent` では、`<Child handleInputTextChange={e => handleInputTextChange(e)}/>` のように、`Child` において制御する関数を `Child` の属性として渡すこと

2. `Child` では `props.handleInputTextChange(e.target.value)` のように `Parent` から受け取る関数の前に `props` をつけること

です。

　どうしてこのようなことが必要になってくるのかというと、React では、[制御されたコンポーネント](https://ja.reactjs.org/docs/forms.html#controlled-components)の考えに基づき、親要素で state を管理することが一般的です。そこで state の管理もハンドラー関数も親要素で管理するとなりますが、その制御関数を子要素に渡すことができないとなると、親要素のファイル上で子要素を定義せざるを得なくなり、コードの量が増えてシンプルではありません。そこで、こういうときは `props` 経由で関数を渡すと良いと思います。もちろん、親子の階層構造がもっと複雑になった場合、state を一箇所で管理する `Redux` の導入も考えられるでしょうが、カンタンなものを作るだけであればこれで十分ではないでしょうか?

### 挙動

#### コードの解説

1. ユーザーが入力するテキストが変化すると、子コンポーネント `Child` の `inputBase` の `onChange` が発火します。

2. `onChange` に指定された関数 `props.handleInputTextChange` は `Parent` から `props` 経由で渡されたものですが、`Parent` における `handleInputTextChange` の定義により、ここで `setInputText` によりstate である `inputText` が更新されます。



3. state が更新されたことを受けて React の DOM ツリーが再描画され、`Parent` の `<p>inputText</p>` 部分が書き換えられます。


#### UI

　UI上の挙動は以下のようになります。　テキストの入力に合わせて、テキストの下に表示されるp要素の内容が変化します。

<img width="700" alt="スクリーンショット 2020-02-15 1.40.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287280/4a3a2a31-e937-cf83-bd09-477d710ac311.png">


<img width="700" alt="スクリーンショット 2020-02-15 1.41.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287280/1499f92b-caf5-f633-b35b-73ac3b02a6a1.png">

　以上です。いいねしてね。