LoginSignup
0
0

Redux-sagaを使ってReactからRubyで作成したAPIに接続する

Posted at

やりたいこと

前提

  • ruby: 2.7 + Rails: 6
  • react: 16.8.6

ファイル構成

app
├── controller
│   └── forms_controller.rb
└── javascript
    ├── app
    │   ├── containers
    │   │   └── Form.js
    │   └── redux
    │       ├── actions
    │       │   └── form.js
    │       └── Saga
    │           ├── api.js
    │           └── index.js
    └── utils
        └── handleCallApi.js

処理手順

コンテナ

  1. 更新ボタンをクリックし、submitForm メソッドを呼び出す。引数にはフォームの入力値values を渡す。
  2. 引数values を変数dataValues に入れる。
    ※引数valuesはimmutableであるため別変数に入れて処理する必要がある。
  3. reduxのdispatch関数でonFetchUpdateForm メソッドを呼び出す。引数には変数dataValue 、正常終了後の処理、異常終了後の処理を渡す。
    app/javascript/app/containers/Form.js
    import React from 'react';
    import { connect } from 'react-redux';
    import { onFetchUpdateFormAction } from "../redux/actions/form";
    import Button from '@material-ui/core/Button';
    
    function Form(props) {
    
      // フォーム入力内容送信
      const submitForm = values => {
        var dataValues = values
        props.onFetchUpdateForm({
          data: dataValues,
          onSuccess: async data => {
            console.log("登録完了")
            // 正常終了後処理を以下記載
          },
          onError: error => {
            console.log("エラー発生")
            // 異常終了後処理を以下記載
          }
        })
      };
    
      return (
        <div>
          {/* フォーム部分省略 */}
          <Button onClick={submitForm}>
            更新
          </Button>
        </div>
      );
    }
    
    // storeからデータ取得
    const mapStateToProps = state => {
      return {
        formData: state.formData,
      };
    };
    
    // storeのデータ更新
    const mapDispatchToProps = dispatch => {
      return {
        onFetchUpdateForm: data => {
          dispatch(onFetchUpdateFormAction(data));
        }
      };
    };
    
    const FormInit = connect(
      mapStateToProps,
      mapDispatchToProps
    )(Form);
    
    export default FormInit;
    

action

  1. onFetchUpdateFormAction メソッドを呼び出すとき、「typeはON_FETCH_UPDATE_FORM で処理する」と定義する。
    app/javascript/app/redux/actions/form.js
    export const onFetchUpdateFormAction = (data) => {
      return {
        type: "ON_FETCH_UPDATE_FORM",
        data
      }
    };
    

Saga

  1. typeがON_FETCH_UPDATE_FORM の時、onFetchUpdateFormAction メソッドを呼び出す。
  2. actionのdata (フォームの入力値)を引数にputUpdateForm メソッドを呼び出す。
    app/javascript/app/redux/Saga/index.js
    import {takeLatest} from 'redux-saga/effects';
    import {Api} from './api';
    
    function* onFetchUpdateFormAction(action) {
      const result = yield Api.putUpdateForm(action.data);
    }
    
    export function* watchOnFetchForm() {
      yield takeLatest("ON_FETCH_UPDATE_FORM", onFetchUpdateFormAction);
    }
    
  3. urlにデータ更新処理を実行するURLを設定する。
  4. callApi メソッドを呼び出す。
    app/javascript/app/redux/Saga/api.js
    import callApi from "../../../utils/handleCallApi";
    
    function* putUpdateForm(data) {
      const url = `http://localhost:3000/forms/${data.data.id}`;
      return yield callApi("put", url, data.data, data.onSuccess, data.onError);
    }
    

API接続

  1. AxiosによってAPIに接続する。引数には、PUTメソッド、接続するURL、タイムアウト時間、フォームの入力値を渡す。
    app/javascript/app/utils/handleCallApi.js
    import Axios from "axios";
    import {csrfToken} from "@rails/ujs"
    
    export default function* callApi(method, url, data = null, onSuccess = null, onError = null) {
      Axios.defaults.headers.common['X-CSRF-Token'] = csrfToken();
      
      try {
        const config = {
          method: method.toUpperCase(),
          url: url,
          timeout: 30000,
          data
        };
        let response = false;
        response = yield Axios(config).then((response) => {
          onSuccess(response);
          return response;
        }, (error) => {
          onError(error);
        });
        return response;
      } catch (error) {
        onError(error);
        return null;
      }
    }
    
  2. AxiosによってRailsのControllerが呼び出され、updateメソッド内の処理が実行される。
    app/controller/forms_controller.rb
    class FormsController < ApplicationController
    
      def update
        # 以下、更新処理記載
      end
    
    end
    
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0