前回に続いて
さて、ここからが本番です。本来ならば Apollo Clientを使うべきなのかもしれませんが、
私の個人的な見解では Apollo Client は相当使いづらいです。
なので、 graphql-request というパッケージを使って、 GraphQLの QueryとMutaionを行います。
サーバーサイドは GraphQLのリクエストさえ飛んでくれば処理できるのでそれで問題なしです!
私はこのやり方が非常に気に入っています。
この記事は5回に分けて連載する、第4回の記事です。
・第1回 Apollo Serverが動くところまで
・第2回 Apollo Server配下で、GraphQLを使って商品マスターにアクセスする
・第3回 フロントエンドをReact+Redux+graphql-requestを使って実装する
・第4回 フロントエンドからgraphql-requestを使って、データを取得・表示する(この記事)
・第5回 graphql-requestを使って、データを登録・修正・削除する
GraphQLアクセスの中心となるcontainerファイルを作成
GET_PRODUCTSで、データをN件取得します。
実際には onLoadData 関数内で GET_PRODUCTSクエリで、GraphQL リクエストを行い、データをN件取得します。
Reduxの containerについてよくわからない場合は、みっちり予習してください。
[bash]
$ nano containers/cproduct.js
[/bash]
[bash]
import {connect} from “react-redux”;
import {GraphQLClient} from “graphql-request”;
import Product from “../components/product”;
import {set_list_body, set_has_more} from “../actions/product”;
const GET_PRODUCTS = `
query GetProducts ($offset: Int!, $limit: Int!){
getProducts(offset: $offset, limit: $limit){
has_more
products {
id
product_name
price
}
}
}
`;
const HOST_ADDR = “http://localhost:4000”;
let LIST_OFFSET = 0;
let LIST_LIMIT = 100;
const mapStateToProps = (state) => {
return {
list_body: state.product.list_body,
has_more: state.product.has_more,
}
}
const mapDispatchToProps = (dispatch) => {
return {
onInit: () => {
LIST_OFFSET = 0;
onLoadData(LIST_OFFSET, [], dispatch)
},
onAddNew: (history) => {
history.push(“/product/add/none”)
},
onLoadMore: (list_body) => {
onLoadData(LIST_OFFSET, list_body, dispatch)
},
}
}
const onLoadData = (offset, list_body, dispatch) => {
const client = createClient();
let variables = {offset: offset , limit: LIST_LIMIT};
client.request(GET_PRODUCTS, variables).then(data => {
let newList = list_body;
for (let i=0; i < data.getProducts.products.length; i++){
newList = newList.concat(data.getProducts.products[i]);
}
dispatch(set_list_body(newList));
LIST_OFFSET += LIST_LIMIT;
dispatch(set_has_more(data.getProducts.has_more));
})
}
const createClient =() => {
const client = new GraphQLClient(HOST_ADDR + “/graphql”, {
headers: {
“x-token”: “test-test”,
},
});
return client;
}
const CProduct = connect(mapStateToProps, mapDispatchToProps)(Product)
export default CProduct
[/bash]
ページ表示時にデータをロードできるようにする
ページを構成する product.jsファイルを編集し、componentDidMountから、
containerの onInitメソッドを呼び出すようにします。
[bash]
$ nano components/product.js
[/bash]
componentDidMount を追記します。
[bash]
import React from “react”;
import Menu from “./menu”;
class Product extends React.Component {
componentDidMount() {
this.props.onInit();
}
render(){
return (
This is Product
)
}
}
export default Product;
[/bash]
App.jsの調整
コンテナファイルを作成しましたが、作成しただけでは利用されないので、
product.jsの代わりに、cproduct.jsを利用するように書き換えます。
[bash]
$nano App.js
[/bash]
components/product.js ではなく、 コンテナ側の containers/cproduct.js を参照します。
[bash]
import React from ‘react’;
import {Router, Route} from “react-router-dom”;
import history from ‘./history’;
import Home from “./components/home”;
import About from “./components/about”;
import CProduct from “./containers/cproduct”;
function App() {
return (
GraphQL と Apollo Serverを使ったマスターメンテナンス
);
}
export default App;
[/bash]
データは読み込まれるか?
これで、serverを npm start し、front も npm start すると
データが読み込まれます。
実際に試してみて、chromeで、デバッグなど入れると、データを読み込めていることが解ると思います。
データ表示部分の作成
肝心の読み込んだデータを一覧表示するところがありませんので、それを記述していきます。
[bash]
$ nano components/product.js
[/bash]
[bash]
import React from “react”;
import Menu from “./menu”;
class Product extends React.Component {
componentDidMount() {
this.props.onInit();
}
render(){
let {list_body, has_more} = this.props;
let lstBody = [];
for (let i = 0 ; i < list_body.length ; i++){
let bd = list_body[i];
lstBody.push(
{bd.id}
{bd.product_name}
{bd.price}
);
}
return (
This is Product
{lstBody}
)
}
}
export default Product;
[/bash]
これで、図のように一覧表示できていたらOKです。
CSSを作成して、デザインをまともに
あとはSCSSで デザイン調整をしましょう。
[bash]
$ npm install –save node-sass
[/bash]
[bash]
$ nano sass/main.scss
[/bash]
[bash]
div.list_products {
div.product_id {
float: left;
width: 90px;
}
div.product_name {
float: left;
width: 250px;
}
div.price {
float: left;
width: 120px;
text-align: right;
}
div.edit {
float: left;
width: 100px;
}
div.clearfix {
clear: both;
}
}
[/bash]
App.jsを編集して、作成したscssを読み込む
[bash]
$ nano App.js
[bash]
[bash]
import “./sass/main.scss”;
function App() {
[/bash]
ボタンを追加して、データを編集できるように
[bash]
$ nano components/product.js
[/bash]
[bash]
import React from “react”;
import Menu from “./menu”;
class Product extends React.Component {
componentDidMount() {
this.props.onInit();
}
render(){
let {list_body, has_more, onClickEdit} = this.props;
let lstBody = [];
for (let i = 0 ; i < list_body.length ; i++){
let bd = list_body[i];
lstBody.push(
{bd.id}
{bd.product_name}
{bd.price}
);
}
return (
This is Product
{lstBody}
)
}
}
export default Product;
[/bash]
お疲れさまでした。とりあえず、今回はここまで。以下のような感じで、一覧データが表示できれば成功です。
次回は、一覧画面から、ボタンクリックで、別画面を表示し、データの編集ができるようにしましょう。

Leave a comment