Udemy-React-Course
  • Introduction
  • CodeSandbox で作る開発環境
    • CodeSandbox を使う利点
    • GitHub との連携
    • CodeSandbox の構造
  • 初めての React App
    • 最小限の React アプリケーションの実装
    • JSX と React Element
    • ES2015 のアロー関数について
    • React でアロー関数を使用する
    • 初めての React Component
    • ES2015 の import / export
    • export default
    • 2章の復習
  • State を持ったコンポーネント
    • State とは何か
    • ES2015 の class
    • React Class Component の書き方
    • click された時に setState で state を変更する
    • H20 Component 1
    • H20 Component 2
    • H20 Component 3
    • H20 Component 4
    • map と filter
    • map と filter の実践
  • 実践:TodoApp の作成
    • TodoApp の作成
  • 非同期処理, Promise, Ajax
    • HTTP プロトコルと AJAX
    • 非同期処理と Promise
    • JSON を取得し、その内容をレンダリングする React App の作成
  • 実践:API を叩く App
    • Giphy API を使用して、GIF画像検索する React App の作成
  • Redux の導入
    • Redux の概要
    • createStore で store を作る
    • Provider と Connect / store を React で使用する
    • Redux の全体像の確認
    • Presentational Component と Container Component
    • Action Creator
    • Combine Reducer
  • Redux-thunk を用いた非同期処理
    • Redux-thunk で非同期にアクションを発行する
    • Promise を Redux-thunk 上で活用する
  • React + Redux + Redux を用いた Giphy App
    • store を作る
    • Component に store を connect する
    • Search コンポーネントの作成
    • GiphyAPI を叩くメソッドの作成と Redux-thunk を使った非同期処理
    • 改善
  • 補足資料
    • App = ({name}) => name 型のシンタックス / Destructuring assignment
    • Class Component と Functional Component の使いわけ
  • 参考資料と謝辞
Powered by GitBook
On this page
  • 小さな修正
  • reducers/imageUrls.js
  • components/ImageList.js
  • APIs/giphyAPI.js
  • ロード状況をボタンに表示する
  • reducers/buttonText.js
  • reducers/index.js
  • containers/Search.js
  • components/Search.js
  • actions/getUrls.js
  • CSS でスタイリングをする
  • index.js
  • App.css
  • components/ImageList.js
  1. React + Redux + Redux を用いた Giphy App

改善

小さな修正

reducers/imageUrls.js

// 初期値を空に
const initialState = [];

components/ImageList.js

無駄に表示されていた URL を消す

import React from "react";

const ImageList = ({ urlList }) => {
  const list = urlList.map(url => {
    return (
      <li key={url}>
        <img src={url} alt="" />
      </li>
    );
  });
  return <ul>{list}</ul>;
};

export default ImageList;

APIs/giphyAPI.js

const giphyApi = word => {
  const search = word;
  const key = "V6AU97qCSCYVmbIC5UDppEiVM1xnuO9E";
  // 表示数を増やす
  const limit = 10;
  const url = `https://api.giphy.com/v1/gifs/search?q=${search}&api_key=${key}&limit=${limit}`;

  return axios.get(url);
};

ロード状況をボタンに表示する

reducers/buttonText.js

新たな reducer を作る

const initialState = "Find Your GIFs";

const imageUrls = (state = initialState, action) => {
  switch (action.type) {
    case "START_REQUEST":
      return "Wait...";

    case "RECEIVE_DATA":
      return initialState;

    default:
      return state;
  }
};

export default imageUrls;

reducers/index.js

buttonText reducer を rootReducer に束ねる

import { combineReducers } from "redux";

import imageUrls from "./imageUrls";
// 新たな reducer をコンバインする
import buttonText from "./buttonText";

export default combineReducers({ imageUrls, buttonText });

containers/Search.js

// state を結びつける
const mapStateToProps = state => {
  return {
    buttonText: state.buttonText
  };
};

const mapDispatchToProps = dispatch => {
  return {
    getUrls: word => {
      dispatch(getUrls(word));
    }
  };
};

// state も追加
export default connect(mapStateToProps, mapDispatchToProps)(Search);

components/Search.js

render() {
    // props として受け取る
    const { buttonText } = this.props;
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <input value={this.state.title} onChange={this.handleChange} />
          {/* button の値に使用する */}
          <input type="submit" value={buttonText} />
        </form>
      </div>
    );
  }

actions/getUrls.js

リクエストが始まる直前に新たなアクションをディスパッチする

import giphyAPI from "../APIs/giphyAPI";

// リクエスト開始用のアクションを作成するクリエイター
const startRequest = () => {
  return {
    type: "START_REQUEST"
  };
};

const receiveData = data => {
  return {
    type: "RECEIVE_DATA",
    payload: data
  };
};

const getUrls = word => {
  return dispatch => {
    // リクエスト直前に実行
    dispatch(startRequest());
    giphyAPI(word).then(res => {
      const data = res.data.data;
      const imageUrlList = data.map(item => item.images.downsized.url);
      dispatch(receiveData(imageUrlList));
    });
  };
};

export default getUrls;

CSS でスタイリングをする

index.js

// CSS を読み込む
import "./App.css";

App.css

body {
  background: wheat;
}

.list {
  height: 100vh;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  list-style: none;
}

.item {
  width: 10%;
}

.image {
  width: 100%;
}

components/ImageList.js

クラスを追加する

import React from "react";

const ImageList = ({ urlList }) => {
  const list = urlList.map(url => {
    return (
      <li className="item" key={url}>
        <img className="image" src={url} alt="" />
      </li>
    );
  });
  return <ul className="list">{list}</ul>;
};

export default ImageList;
PreviousGiphyAPI を叩くメソッドの作成と Redux-thunk を使った非同期処理Next補足資料

Last updated 7 years ago

https://codesandbox.io/s/l4j8zj4poz
https://codesandbox.io/s/4z7oy358vw