LoginSignup
2
4

More than 5 years have passed since last update.

redux-formを使って自作APIにデータを送った

Posted at

概要

自分用勉強メモです。
redux-formを使ってみました。名前を入力してそのデータをjson-serverで作ったデータベースに送ってみたいと思います。

json-server公式
https://www.npmjs.com/package/json-server

フォームを作る

名前を入力するフォームを作っていきます。
まず必要なライブラリをインストールします。

npm install --save redux react-redux redux-form redux-thunk axios

データベースと非同期通信するのでredux-thunkとaxiosを取ってきます。
まずsrc/index.js

src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';

import App from './components/App';
import reducers from './reducers';

const store = createStore(
  reducers,
  applyMiddleware(thunk)
);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#root')
)

いつも通りの雛形です。
次にreducerをみてみます。

src/reducers/index.js
import { combineReducers } from "redux";
import { reducer as formReducer } from 'redux-form';

export default combineReducers({
  form: formReducer
});

ここでredux-formからreducerを取っています。
reducerだとわかりにくいのでasを使ってformReducerとしています。
メインのApp.jsを見ていきます。

src/components/App.js
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

class App extends Component {
  renderInput({input}) {
    return (
      <div>
        <label>name</label>
        <input {...input} />
      </div>
    );
  }

  onSubmit = () => {
    //データベースと通信するアクションを書く
  }

  render() {
    return (
      <form onSubmit={this.props.handleSubmit(this.onSubmit)}>
        <Field name="name" component={this.renderInput} />
      </form>
    );
  }
}

export default reduxForm({
  form: "nameList"
})(App);

ここでredux-formからField, reduxFormを取っています。
見ればわかる通り、Fieldがフォームとなる部分になります。
FieldにはnameとcomponentがありますがnameはそのフォームをformValuesで参照することができます。
つまり、空白で送って欲しくないバリデーションをつけたい場合、上記の例では

if (!formValues.name) {
  //エラーの時出したい処理
}

のようになります。
renderInput()のところにはformPropsがくるのですが、formProps.inputには便利なものがたくさん入っているので、それらを{...formProps.input}としてとるところを簡潔に{...input}と書いています。
気になればconsole.log(formProps);してみてください。
あとはhandleSubmitのメソッドを使って送れるのでそこにjson-serverと通信するアクションを乗せてあげます。

その前に、データベースを作りましょう。

データベースを作る

mkdir api
cd api
npm init
npm install --save json-server

新たにディレクトリを作り、npm initでpackage.jsonを取得し、json-serverをインストールします。
apiフォルダを開いて必要なファイルを作ります。

db.json
{
  "nameList": []
}

送ったデータを配列で管理するようにします。
次にpackage.jsonを少しいじります。

package.json
{
  "scripts": {
    "start": "json-server -p 3001 -w db.json"
  }
}

"scripts"のところを上記のようにします。
3001のポートでdb.jsonを参照するというコードです。
最後にnpm startでapiを起動しましょう。

仕上げ

次にaxios.createを使ってベースを作ります。

src/apis/nameList.js
import axios from 'axios';

export default axios.create({
  baseURL: "http://localhost:3001"
});

そのままアクションも作りましょう。

src/actions/index.js
import nameList from '../apis/nameList';

export const submitName = (formValues) => async (dispatch) => {
  await nameList.post('/nameList', formValues)
};

postを使って入力された文字を送信するアクションです。postの第一引数にはdb.jsonで書いた配列のキーが入ります。
最後にApp.jsで仕上げます。

src/components/App.js
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import { submitName } from '../actions';

class App extends Component {
  renderInput({input}) {
    return (
      <div>
        <label>name</label>
        <input {...input} />
      </div>
    );
  }

  onSubmit = (formValues) => {
    this.props.submitName(formValues);
  }

  render() {
    return (
      <form onSubmit={this.props.handleSubmit(this.onSubmit)}>
        <Field name="name" component={this.renderInput} />
      </form>
    );
  }
}

const formWrapped = reduxForm({
  form: "nameList"
})(App);

export default connect(null, { submitName })(formWrapped);

これでフォームに何か入力してエンターを押すとデータベースに保存されるはずです。
デベロッパーツールのネットワーク、ターミナルでcat db.jsonで送った内容が保存されてidが付いていると思います。

まとめ

今回はredux-formを使ってみました。
まだまだわからないことが多いので知識を蓄えていきたいと思います。
参考になれば幸いです。

2
4
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
2
4