masalibの日記

システム開発、運用と猫の写真ブログです

reactでcookieを扱う

社内の勉強会でreactをおこなっているのですがcookieを扱う部分ではまってしまい、5人がかかりで調査したのですがわからず宿題になってしまいました

react-cookie

react-cookieというモジュールをインストールをしたのですがサンプルの理解できず時間がかかってしまいました自分の理解も含めてブログにのこします

モジュールインストール

create-react-appでサンプルappを作成します
その後、今回使用する「react-cookie」をインストールする

cd 適当なフォルダ(自分の場合はc:\git)
create-react-app cookie
cd cookie
npm install react-cookie
npm install 

index.jsの修正

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { CookiesProvider } from 'react-cookie'	// ←react-cookeもモジュールを読み込む

// デフォルトのappのタグに対してCookiesProviderをくくる
ReactDOM.render(
  <CookiesProvider>
    <App />
  </CookiesProvider>, document.getElementById('root') )
registerServiceWorker()

index.js側でcookieを受けれるcreate-react-appでサンプルappを作成します
その後、今回使用する「react-cookie」を設定する

app.jsの修正

ソースです

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { withCookies, Cookies } from 'react-cookie';
import PropTypes from 'prop-types';	// 解説1

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};		// 解説1
    this.handleChange = this.handleChange.bind(this);	// 解説1
    this.handleNameChange = this.handleNameChange.bind(this);	// 解説1
  }

  
  componentWillMount() {
    const { cookies } = this.props;		// 解説2
      this.state = {
      name: cookies.get('name') || '名無しさん'	// 解説2
    };
  }
  handleChange(event) {
    this.setState({value: event.target.value});	// 解説3
  }

  handleNameChange(event) {
    const { cookies } = this.props;			// 解説3
    var name = this.state.value;			// 解説3
    cookies.set('name', name, { path: '/' });	// 解説3
    this.setState({ name });			// 解説3
  }

  render() {
    return (
      <div className="App">
		<!-- 解説4 -->
        <h1>Hello {this.state.name} </h1>
        <form onSubmit={this.handleNameChange}>
          <label>
            Name:
            <input type="text" value={this.state.value}  onChange={this.handleChange}/>
          </label>
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}

export default withCookies(App);// 解説5
app.jsの修正の解説1
	import PropTypes from 'prop-types';	

prop-typesをimportしています
Propは基本的にはCompnentのattributeとして定義してComponentの中ではthis.props.xxxとして参照する

    this.state = {value: ''};		
    this.handleChange = this.handleChange.bind(this);	
    this.handleNameChange = this.handleNameChange.bind(this);	

this.handleChangeとthis.handleNameChangeで
this.setStateを使うために設定する

app.jsの修正の解説2
  componentWillMount() {
    const { cookies } = this.props;
  
    this.state = {
      name: cookies.get('name') || '名無しさん'
    };
  }

ComponentがDOMツリーに追加される前に一度だけ呼ばれます。
なので初期化処理を行うのに適しています。
この中でsetStateするとrender時にまとめて行われます。<<qiita.com
より引用

this.state = {name: cookies.get('name') || '名無しさん'};
の部分でcookiesから取得してもしなかったら名無しさんを設定しています

app.jsの修正の解説3
  handleChange(event) {
    this.setState({value: event.target.value});	
  }

  handleNameChange(event) {
    const { cookies } = this.props;			
    var name = this.state.value;			
    cookies.set('name', name, { path: '/' });	
    this.setState({ name });			
  }

handleChangeの関数では
テキストボックスで入力した内容をリアルタイムで
Stateに保存しています

handleNameChangeの関数では
state.valueにある内容をcookieにセットしています

app.jsの修正の解説4
<!-- 解説4 -->
<h1>Hello {this.state.name} </h1>
<form onSubmit={this.handleNameChange}>
  <label>
    Name:
    <input type="text" value={this.state.value}  onChange={this.handleChange}/>
  </label>
  <input type="submit" value="Submit" />
</form>

{this.state.name}は初期設定している内容または変更した内容を出力している

<input type="text" value={this.state.value}  onChange={this.handleChange}/>

は入力した内容を変更されるたびにonChangeで設定されているthis.handleChangeが
呼ばれて、テキストボックスの内容をthis.state.valueにいれている

<form onSubmit={this.handleNameChange}>

はthis.state.valueの内容をcookieとthis.state.nameにいれています

app.jsの修正の解説5
export default withCookies(App);

レンダリングの部分に加えて、cookieも返すという部分
これがないとcookieがindexに返さないので保存ができない


感想

めんどくさい・・・
もう少し楽なればいいのにと思う