React学習記録1日目

##Progate React I
###作ったもの
ボタンをクリックするとテキストが切り替わる機能

###学んだこと
- renderメソッドの中にHTMLを書いていく記法を`JSX`と呼ぶ
- renderメソッドの上にJavaScriptの式を書いていく
- JSX内で利用や変更していく値を`state`として定義する
- stateは`constructor`の中に定義する
- `{}`を使ってJSX内にJavaScriptを埋め込むことができる

###ソース(抜粋)
```react:App.js
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {name: 'にんじゃわんこ'};
  }  
  handleClick(name) {
    this.setState({ name: name })
  }
  
  render() {
    return (
      <div>
    	<h1>こんにちは、{this.state.name}さん！</h1>
        <button onClick={ () => { this.handleClick('ひつじ仙人') } }>ひつじ仙人</button>
        <button onClick={ () => { this.handleClick('にんじゃわんこ') } }>にんじゃわんこ</button>  
      </div>
    );
  }
}

export default App;
```

##Progate React Ⅱ
###作ったもの
言語一覧画面

###学んだこと
- 作成した`App.js`は`index.js`にインポートされ、最終的に`index.html`に埋め込まれる
- JSXにクラスをつける時は`className='クラス名'`と書く
- `export default`で外部ファイルから読めるようにして、`import`で読み込む
- 親→子コンポーネントに渡すデータを`props`と呼ぶ
- propsは、子コンポーネントを呼び出す時に渡す
- 渡されたpropsは子コンポーネントから`this.props.hoge`でアクセスできる
- 繰り返し処理は`map`関数を使う

###ソース(抜粋)
```src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';

ReactDOM.render(<App />, document.getElementById('root'));
```
```jsx:src/components/App.js
import React from 'react';
import Language from './Language';

class App extends React.Component {
  render() {
    const languageList = [
      {
        name: 'HTML & CSS',
        image: 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/html.svg'
      },
      {
        name: 'JavaScript',
        image: 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/es6.svg'
      },
      {
        name: 'React',
        image: 'https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/react/react.svg'
      }
    ];

    return (
      <div>
        <h1>言語一覧</h1>
        <div className='language'>
          {languageList.map((languageItem) => {
            return (
              <Language
                name={languageItem.name}
                image={languageItem.image}
              />
            )
          })}
        </div>
      </div>
    );
  }
}

export default App;
```
```jsx:src/components/Language.js
import React from 'react';

class Language extends React.Component {
  render() {
    return (
      <div className='language-item'>
        <div className='language-name'>{this.props.name}</div>
        <img 
          className='language-image' 
          src={this.props.image} 
        />
      </div>
    );
  }
}

export default Language;
```

##Progate React Ⅲ
###作ったもの
モーダル

###学んだこと
- JSXの中で変数を定義、利用することができる
- 変数の中にJSXの中身を入れることができる

###ソース(抜粋)
```jsx
class Lesson extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isModalOpen: false};
  }
  render() {
    let modal //変数modalを定義
    if(this.state.isModalOpen) { //stateの状態でmodalの中身を変更
      modal = (
        <div className='modal'>
          <h2>{this.props.name}</h2>
          <button className='modal-close-btn'>とじる</button>
        </div>
      )
    } 
    return (
      <div className='lesson-card'>
        <p>{this.props.name}</p>
        <img src={this.props.image} />
        { modal } //modalを利用
      </div>
    );
  }
}
```

##Progate React Ⅳ
###作ったもの
問合せフォーム（エラーチェックと送信後画面の切り替え。実際にデータは送信していない）

###学んだこと
- `<input />`、`<textarea />`、`<img />`など、JSXにはHTMLと微妙に書き方が違うタグがあるので注意
- formに入力された値をstateに反映するには`onChange={(event) => {this.hogemethod(event)}}`のように引数に`event`を指定して関数を呼び出す
    - 関数内では`event.target.value`で値を取り出す

###ソース(抜粋)
```react:src/components/ContactForm.js
import React from 'react';

class ContactForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isSubmitted: false,
      email: '',
      hasEmailError: false,
    };
  }

  handleEmailChange(event) {
    const inputValue = event.target.value;
    const isEmpty = inputValue === '';
    this.setState({
      email: inputValue,
      hasEmailError: isEmpty,
    });
  }
  handleSubmit() {
    this.setState({isSubmitted: true});
  }

  render() {
    let emailErrorText;
    if (this.state.hasEmailError) {
      emailErrorText = (
        <p className='contact-message-error'>
          メールアドレスを入力してください
        </p>
      );
    }
    let contactForm;
    if (this.state.isSubmitted) {
      contactForm = (
        <div className='contact-submit-message'>
          送信完了
        </div>
      );
    } else {
      contactForm = (
        <form onSubmit={() => {this.handleSubmit()}} >
          <p>メールアドレス（必須）</p>
          <input
            value={this.state.email}
            onChange={(event) => {this.handleEmailChange(event)}}
          />
          {emailErrorText}
          
          <input
            type='submit'
            value='送信'
          />
        </form>
      );
    }
    
    return (
      <div className='contact-form'>
        {contactForm}
      </div>
    );
  }
}

export default ContactForm;
```

##Progateで実装した機能をローカルで再現
今3/4くらいです。終わったら手順を別記事でアップします。