Giphy API を使用して、GIF画像検索する React App の作成
Giphy API の Key を取得する
- アカウントを作成する
- API Key を取得する
Giphy API をたたく
問い合わせ先の URL
const search = "cat";
const key = "V6AU97qCSCYVmbIC5UDppEiVM1xnuO9E";
const limit = 3;
const url = `https://api.giphy.com/v1/gifs/search?q=${search}&api_key=${key}&limit=${limit}`;
axios でリクエストをし、得た情報を DOM に反映させる
https://codesandbox.io/s/ylyn217wv
import axios from "axios";
const search = "cat";
const key = "V6AU97qCSCYVmbIC5UDppEiVM1xnuO9E";
const limit = 3;
const url = `https://api.giphy.com/v1/gifs/search?q=${search}&api_key=${key}&limit=${limit}`;
axios.get(url).then(res => {
console.log(res.data);
const data = res.data.data;
// 全てのデータの中から、仮に最初の要素の、gif 用 URL を取り出す
// この URL が画像を取得する際に必要となるもの
const imageUrl = data[0].images.downsized.url;
console.log(imageUrl);
// img 要素を生成して、body 直下に強引に入れ込む
const img = document.createElement("img");
img.src = imageUrl;
document.body.appendChild(img);
});
React App に組み込む
https://codesandbox.io/s/x3o73pzz4q
import React from "react";
import { render } from "react-dom";
import axios from "axios";
class App extends React.Component {
constructor() {
super();
// image の url のリストを持つ
this.state = { gifUrlList: [] };
}
// コンポーネントがマウントされた時に実行される
componentDidMount() {
this.giphyApi();
}
render() {
console.log(this.state.gifUrlList);
return <div>app</div>;
}
// API を叩いて、その結果を state に反映させるメソッド
giphyApi() {
// リクエスト先の URL を作る
const search = "cat";
const key = "V6AU97qCSCYVmbIC5UDppEiVM1xnuO9E";
const limit = 3;
const url = `https://api.giphy.com/v1/gifs/search?q=${search}&api_key=${key}&limit=${limit}`;
// axios でリクエストをする
axios.get(url).then(res => {
const data = res.data.data;
// 必要な URL の配列を作る
const imageUrlList = data.map(item => item.images.downsized.url);
// state を取得した情報を元に変更する
this.setState({ gifUrlList: imageUrlList });
});
}
}
render(<App />, document.getElementById("root"));
img 要素をレンダリング
https://codesandbox.io/s/7mpkvy49w1
// img 要素のリストを作るメソッド
renderImageList(list) {
const imageList = list.map(url => {
return (
<li>
<img src={url} />
</li>
);
});
return <ul>{imageList}</ul>;
}
// 上記メソッドをレンダー内で使用する
render() {
console.log(this.state.gifUrlList);
return <div>{this.renderImageList(this.state.gifUrlList)}</div>;
}
検索窓を作る
https://codesandbox.io/s/n0ppvpzqm4
todoApp で作ったコンポーネントを活用して Search コンポーネントを作る
components/Search.js
import React from "react";
export class Search extends React.Component {
constructor(props) {
super(props);
this.state = { title: "" };
}
render() {
return (
<div>
<h2>Find Your GIF</h2>
<form onSubmit={this.handleSubmit}>
<input value={this.state.title} onChange={this.handleChange} />
<input type="submit" value="Search!!" />
</form>
</div>
);
}
handleChange = event => {
const title = event.target.value;
this.setState({ title: title });
};
handleSubmit = event => {
event.preventDefault();
// 受け取ったメソッドを実行し、app の state を変更している
this.props.search(this.state.title);
this.setState({ title: "" });
};
}
Search Component を配置する
// addTodo を再利用したコンポーネントを読み込む
import { Search } from "./components/Search";
class App extends React.Component {
// 省略
render() {
// Search コンポーネントを使用する
return (
<div>
<Search search={this.giphyApi} />
{this.renderImageList(this.state.gifUrlList)}
</div>
);
}
Search コンポーネントにメソッドを渡す
App.js
render() {
// Search コンポーネントにメソッドを渡す
return (
<div>
<Search search={this.giphyApi} />
{this.renderImageList(this.state.gifUrlList)}
</div>
);
}
Search コンポーネントの中で受け取ったメソッドを実行する
Search.js
handleSubmit = event => {
event.preventDefault();
// 受け取ったメソッドを実行し、app の state を変更している
this.props.search(this.state.title);
this.setState({ title: "" });
};
検索対象を引数として受け取って使用する
index.js
// 検索対象を target という引数で受けて使用する
giphyApi = target => {
const search = target;
const key = "V6AU97qCSCYVmbIC5UDppEiVM1xnuO9E";
const limit = 10;
const url = `https://api.giphy.com/v1/gifs/search?q=${search}&api_key=${key}&limit=${limit}`;
axios.get(url).then(res => {
const data = res.data.data;
const imageUrlList = data.map(item => item.images.downsized.url);
this.setState({ gifUrlList: imageUrlList });
});
};
CSS でスタイリング
https://codesandbox.io/s/8vxy99n28
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%;
}
クラスネームを付与する
index.js
renderImageList(list) {
const imageList = list.map(url => {
return (
<li className="item">
<img className="image" src={url} />
</li>
);
});
return <ul className="list">{imageList}</ul>;
}