エンジニアスタンプラリー～フロントエンド編＃8

## 企画主旨
[Frontend Developer Roadmap](https://roadmap.sh/frontend)をひたすら巡回する企画 
詳しくは[こちら](https://qiita.com/tonchan1216/items/8d5f072cf769dfe1bc4f)

## 今回の実施内容
フレームワーク
React vs Angular vs Vueみたいなテーマで盛り上がりを見せている。

## Pick a Framework

#### React.js
黄色テーマのReact.jsを選択。
割と公式資料が内容薄だったので、[今から始めるReact入門 〜 React の基本](https://qiita.com/TsutomuNakamura/items/72d8cf9f07a5a30be048)の記事を参考にさせていただいた。
今までの成果物をReactベースに書き換え。
デザインは前回同様だが、中身はほとんど書き換わった。

```react:main.js
import React from 'react';
import ReactDOM from 'react-dom';

import 'jquery';
import 'popper.js';
import 'bootstrap';
import '../sass/main.scss';

import Header from './components/Header/header';
import Content from './components/content';
import Footer from './components/footer';

class Layout extends React.Component {
  constructor() {
    super();
    this.state = {
      status: {
        front: 'active',
        back: 'inactive'
      }
    };
    this.togglePages = this.togglePages.bind(this);
  }

  togglePages(item) {
    this.setState({
      status: {
        front: item === 'front' ? 'active' : 'inactive',
        back: item === 'back' ? 'active' : 'inactive'
      }
    });
  }

  render() {
    const { status } = this.state;
    return (
      <div className="container">
        <Header togglePages={this.togglePages} status={status} />
        <Content status={status} />
        <Footer />
      </div>
    );
  }
}

const app = document.getElementById('app');
ReactDOM.render(<Layout />, app);
```

### Redux
状態管理。初めまして。
今回も公式ではなく、[Redux入門【ダイジェスト版】10分で理解するReduxの基礎](https://qiita.com/kitagawamac/items/49a1f03445b19cf407b7)を参考にさせていただいた。本当にわかりやすかった。
理解はしたが、利便性までは理解できず。。。

```javascript:reducers.js
export default (state = initialState, action) => {
  const invert = state.page === 'front' ? 'back' : 'front';

  switch (action.type) {
    case CHANGE_TEXT:
      return { ...state, inputText: action.text };
    case UPDATE_NEWS:
      return { ...state, news: action.news };
    case ADD_SKILL:
      return {
        ...state,
        inputText: '',
        skill: {
          [state.page]: state.skill[state.page].concat(action.text),
          [invert]: state.skill[invert]
        }
      };
    case TOGGLE_PAGE:
      return { ...state, page: action.page };
    default:
      return state;
  }
};
```

```javascript:App.js
class App extends React.Component {
  componentDidMount() {
    const { dispatchUpdateNews } = this.props;
    const url = 'assets/tenki.json';
    fetch(url)
      .then(response => response.text())
      .then(text => {
        const json = JSON.parse(text);
        const jsonForecasts = json.forecasts[0];
        dispatchUpdateNews(`${jsonForecasts.date}：${jsonForecasts.telop}`);
      });
  }

  render() {
    const {
      dispatchAddSkill,
      dispatchtogglePage,
      dispatchChangeText,
      skill,
      page,
      news,
      inputText
    } = this.props;
    return (
      <div className="container">
        <Header togglePage={dispatchtogglePage} page={page} />
        <Content
          skill={skill}
          page={page}
          news={news}
          inputText={inputText}
          addSkill={dispatchAddSkill}
          changeText={dispatchChangeText}
        />
        <Footer />
      </div>
    );
  }
}

export default connect(
  state => ({
    skill: state.skill,
    page: state.page,
    news: state.news,
    inputText: state.inputText
  }),
  dispatch => ({
    dispatchUpdateNews: news => dispatch(updateNews(news)),
    dispatchAddSkill: text => dispatch(addSkill(text)),
    dispatchtogglePage: page => dispatch(togglePage(page)),
    dispatchChangeText: text => dispatch(changeText(text))
  })
)(App);
```

### MobX
Reduxと比較される状態管理のライブラリ。
上記で参考にした同シリーズ[今から始めるReact入門 〜 Mobx 編](https://qiita.com/TsutomuNakamura/items/f10491060f0f1640afd9)を参考にさせていただいた。
ベースはReduxのまま、ちょっと簡潔に書きやすくなったかな。という印象。

```javascript:SkillStore.js
import { observable, computed, action } from 'mobx';

export default class SkillStore {
  @observable news = '';

  @observable inputText = '';

  @observable page = 'front';

  @observable.shallow skill = {
    front: [],
    back: []
  };

  @computed get getInputText() {
    return this.inputText;
  }

  @action.bound changeText(text) {
    this.inputText = text;
  }

  @action.bound updateNews(news) {
    this.news = news;
  }

  @action.bound addSkill() {
    if (this.inputText === '') return;
    this.skill[this.page] = this.skill[this.page].concat(this.inputText);
    this.inputText = '';
    // console.log(this.skill[this.page]);
  }

  @action.bound togglePage(page) {
    this.page = page;
  }
}
```

## 成果物
コード量も多くなり、記事的にあまり載せられないのが残念。
HTMLを生で書いていたあの頃からだいぶ成長したアプリケーション。
https://tonchan1216.github.io/WDR-frontend/v8/
https://github.com/tonchan1216/WDR-frontend/tree/v8.0