manmanrai’s diary

勉強記録ブログ

自社サイトのABテスト事情

マーケティングの部署に入ってもうすぐ3か月が経つが、 自社サイトのABテストずっと傍観者という謎の立ち位置でミーティングに参加していて、 正直自社と外部パートナーさんの仕事の差があまり分からなかった。

自社のマーケティンググループと外部のパートナーさんの仕事:
【アイデア出し】→【工数検討】→【テスト実施】→【本番反映する】
ページごとに分けて一部は自社の人間がテスト回している。
たまに、外部パートナーさんがやった後に、引き続きは自社でやる、また、逆の場合もある。

毎週定例ミーティング(パートナーさん出てもらってる)はうちのボスに報告する会
「このページはベース案が勝ちましたねー」「これは新しい作った案が勝ってますねー」
こんな風に報告を受け、ボスがふむふむと聞いている、たまに中断して意見を出す。
ほかの社員みんなほぼずっとぼーっとしている。なぜかというと、みんな決定権がないから。

どうしてこうなったのって、まだ入社日が浅い私には言えないけど、
でも多分誰がこのミーティング入っても同じこと思うんでしょう。
おかしい、このミーティング絶対おかしい。

外部パートナーさんはあまり提案してくれないし、コーディングも別の人に依頼しているし、ただアイデアリスト(スプレッドシート)を整理してくれて、「このテストなら御社の○○さんならできそうですね」って言ってくれるだけ(このテストパートナーさんやらないのか?)、
どうしてこのパートナーさんと付き合うことになったんだろうとずっと疑問を感じていて、ある日、この疑問をボスにぶつけてみた。
「どうしてその会社さんとそのミーティングをやってるんですか?社内でもできれば毎月〇百万円を節約できるじゃないですか?」
「今おれ以外誰も今までの歴史分からないし、人手も足りないから」という返答が返ってきた。

テスト積み重ねてきた歴史を守りたい、重複したテストは時間の無駄かも、過去にはそのテストをやってコンバージョンすごく下げたことも分からない人間にテスト勝手に回す権利なんて与えてはいけない。
ボスの考えは分からなくはない、リスクは確かに避けれるなら避けたい。
しかし、ほぼボス一人のためのミーティング、パートナーさんの社長さん、ディレクター4人出席してもらうの、
うちらの社員たちのお時間も抑えてるし、無駄が多いと思う。

まして、パートナーさんと仲が良いので、最初の会社の節約のためのパートナーさん排除計画はもう諦めてた。
でも、この現状やはり変えたい。(平社員の野望)

ボスは社歴14年で、HPに関して一番詳しいかもしれないが、ABテストに関わっている社員たちみんな社歴1年未満。分からないって当たり前。
使ってるツールはKaizenPFとKARTEで、一覧性がないので、一ラウンド一ラウンドのデザインを開いて調べるの時間かかるし、得られる情報も少ないので、忙しいみんなさんは無理。
だから誰も過去を知らない、知りたいならボスに聞くしかない。いざこのページにテスト自分が担当することになったら、初めてそのKaizenのページを開く。非常に非効率的。

そして、自分からボスに提案してみた。
【改善可視化プロジェクト】
問題:
途中で改善プロジェクトに入ってきた人がすぐ全体を把握できない。
1人ひとりが俯瞰的な視点持たずに進むとサイト全体の方向性がバラバラになる。
既存メンバーが今までの改善の歴史を共有する時間がないので、新しい入ってきた人は自力で探るしかない。

具体的に言うと、どのページは何をやってきたのか(せめて、今はどんな施策を行っているのか)、最後にどの案をやって止まってるのか、止める理由は何(キャパがない、急ぎではない、新しいアイデアがない)

そしていくつ提案した。
ページ単位でカードを作る、項目埋め込んでもらう、そしてそれをチームメンバーに共有する。
パッと見てパッと分かるようなものを作りたい。(壁に貼るやつもあったら最高だけど、うちの会社にはそういうのできないみたい)
社内ABテストのwikipediaを作ってみる。一覧性はないけど、誰でも手軽に更新できる。
などなど。

これでよい方向に向かってるかどうか自分でも分からないけど、ぼちぼち色んな方法試してみたいと思う。
まずwikipediaを作ってみた。seesaa wiki無料なので、これを選んだ。

wiki.seesaa.jp

軸は二つ「仮説」と「ページ」
仮説を立てて、そしてその仮説に関わる全てのページを結び付ける。
エクスペリエンス、ラウンドを「ページ」内に記述する。
書き方完全自分流だけど、一旦今実施してる「仮説」の中身を充実させる、どういう背景があって、今回はどういう試みとか、そしてKaizenPFでのデザイン変更点もwikiに持ってくる。 同じページに今まで実施してきたものを同じところに入れたいけど、絶対大変な作業なると思う。 この段階終えたら、一回ボスに見せようか。

【追記】

wiki試作して出したが、ボスからの反応がよくて、しかし実際に進めるかどうか怪しい。

問題はどこにあるか分かった。
もしかして、ボスはプレイヤーでいたいということを気づきました。
手放したくないかもしれないので、情報共有に積極ではない。難航。

React.jsもくもく会参加してみました(ほぼ雑談)

昨日はじめてReact.jsのもくもく会参加してみました。
場所はYahooのコワーキングスペースです。
恐らく百人以上余裕で入れるスペースなんですが、朝からものすごく混雑していました。

実際の状況はどうだったかというと

React.js勉強しはじめて、日がまだ浅い、全員はじめましてという状況でもあり、 このもくもく会で同じ初心者に出会えるのかなという小さな願いを抱えて臨みました。

(多分どうでも良い)発見

→自分と同じく脱jQueryという目標に向かってる人いた
→なぜか起業家が多い(やはりideaあったらすぐ実現する(させる)のが大事!)
→なぜかアメリカ留学経験持ちの方多い
→皆やりたいことはっきりしている(当たり前かもしれません、、)

(多分どうでも良い)感想

→入り早々自分もしかして軽くコミュ障疑惑浮上(自分から発言しないのかい)
→自己紹介噛んでなかったことにやや自慢できるんじゃないかと思った(レベル低すぎ)
→皆レベル高すぎ、聞いたこと無い単語の多発によりさらにコミュ障発作(正直心折れた)
→ランチ会でちょっとした雑談できたこと自分に誇りを持った(自分に甘い)

最後に

メモ:
1. redux
React Redux
Redux ExampleのTodo Listをはじめからていねいに(1)) 2. puredux
もうReduxで疲弊しない。Pureduxで始めるRedux。
3. Flux
React & Flux入門
10分で実装するFlux
【React.js】Fluxの概念を勉強するときにとっても役に立った記事まとめ
ReactとFluxとReduxについて順を追って整理する

今までReact.jsというキーワードで検索したらよくセットで出てくるものがいっぱいありましたが、実はまだ一つの触れてませんでした。
今作りたい機能について質問した時にreduxをおすすめされましたので、まずそこからはじめたいと思います。
多分それぞれに大事な概念が含まれてると思いますので、焦らずにゆっくりじっくり勉強していきたいと思います。(実は結構せっかち)
開催者のにしむらさん、 初心者の私も優しく答えてくださって、誠にありがとうございました。

次回お会いした時、皆の話ちょっとでも理解できるようになりたいです。
頑張ります。

React.jsで簡易todo listを作ってみた(codepen, github)

プロローグ

React.js公式サイト(英語)

一通りReact.jsのDocumentのinstallationとquick startを実践しながら勉強しました。
実際に自分どこまで理解できたのか知りたいので、簡単なWeb applicationを作ってみようかなと。
初心者向けの課題によく出て来るtodo listを選びました。

この記事の最後に完成したサンプル(codepen)とgithubのリンク貼り付けておりますので、ご参考にしていただければ幸いです。

要件定義

簡易バージョンなので、最低限のものだけ作りたいと思います。
- 書き込める場所
- 保存するボタン
- Todo Listを表示させる
(修正不可、削除不可)

ゴール:

完成したtodo list

参考サイト(英語)

1. Simple React todo list – Agata Krzywda – Medium

今回の勉強記録はこの記事の内容を整理しつつ、公式サイトと見比べながら書き換えたものになります。

スタート

(ターミナルで)
tutorialでインストールしたReactのcreate-react-appコマンドを使って、todolistフォルダを作成します。

$ create-react-app todolist

フォルダ内に移動します。

$ cd todolist
$ npm start

自動的にローカルでブラウザ立ち上がり、React.jsページのデフォルトの状態が表示されます。

そして、エディターでフォルダを開くと、構造は
-node_modules/
-public/
-src/
-package-lock.json
-package.json
-README.md
になっています。

/src/app.js
/src/index.js
デフォルトの書き方は主に記述内容はapp.js内で書いて、index.js内でapp.jsを呼び込んで、/public/index.html内で描きます。

実行されるものはindex.jsなので、今回はapp.jsを使わずに、index.jsだけ使いたいと思います。

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

いらないものを削除して、これだけ残します。
そして、app classをimportの後に追記します。
formを作って入れます。

import React from 'react';
import ReactDOM from 'react-dom';

class App extend React.Component {
    render() {
        return(
            <div>
                <form>
                    <input type="text" value="" />
                    <input type="submit" value="Submit" />
                </form>
            </div>
        );
    }
}

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

Appの構造を定義します。

   constructor(props) {
        super(props);
        this.state = {
            term: '',
            items: []
        };
    }

そして、functionは2つあります。
onChangeはinput内に書いたら、inputのvalueに保存する→[term]
onSubmitは先ほど保存したvalueをstate内のitemsにパスする→[items]

constructor内でfunctionを結びついてから、functionを書きます。

   constructor(props) {
        super(props);
        this.state = {
            term: '',
            items: []
        };

        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }

    onChange(e) {
        this.setState({
            term: e.target.value
        });
    }

    onSubmit(e) {
        e.preventDefault();
        this.setState({
            term: '',
            items: [...this.state.items, this.state.term]
        });
    }

...this.state.items
という書き方はquick start内には説明してなかったけど、advanced guide内にはありました。

JSX In Depth - React

すべての〇〇という意味です。ここはすべてのthis.state.itemsです。

そして、renderで書いてたform内のfunctionと繋げます。
formの書き方こちらを参照してます。

Forms - React

   render() {
        return (
            <div>
                <form onSubmit={this.onSubmit}>
                    <input type="text" value={this.state.term} onChange={this.onChange} />
                    <input type="submit" value="Submit" />
                </form>
            </div>
        );
    }

最後、todo listを表示するために、functionを作ります。
mapの書き方こちらを参照してます。

Lists and Keys - React

function List(props) {
    const items = props.items;
    const listItems = items.map((item, index) => 
        <li key={index}>
            {item}
        </li>
    );
    return(
        <ul>
            {listItems}
        </ul>
    );
}

class App内のreturnをを追記して、this.state.itemsと繋げます。

   render() {
        return (
            <div>
                <form onSubmit={this.onSubmit}>
                    <input type="text" value={this.state.term} onChange={this.onChange} />
                    <input type="submit" value="Submit" />
                </form>
                <List items={this.state.items} />
            </div>
        );
    }

最終的にまとめてみると、こうなります。

import React from 'react';
import ReactDOM from 'react-dom';


function List(props) {
    const items = props.items;
    const listItems = items.map((item, index) => 
        <li key={index}>
            {item}
        </li>
    );
    return(
        <ul>
            {listItems}
        </ul>
    );
}


class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            term: '',
            items: []
        };

        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }

    onChange(e) {
        this.setState({
            term: e.target.value
        });
    }

    onSubmit(e) {
        e.preventDefault();
        this.setState({
            term: '',
            items: [...this.state.items, this.state.term]
        });
    }

    render() {
        return (
            <div>
                <form onSubmit={this.onSubmit}>
                    <input type="text" value={this.state.term} onChange={this.onChange} />
                    <input type="submit" value="Submit" />
                </form>
                <List items={this.state.items} />
            </div>
        );
    }
}


ReactDOM.render (
    <App />,
    document.getElementById('root')
);

ブラッシュアップ

テストで何件タスクを入れてみましたが、改善点を見つけました。
例えば、間違えてenter(return)を押したら(=submitボタンを押したら)、空白のままでリストに入っちゃうので、それをブロックしたいです。

最後に空白なら追加しないようにonSubmit functionに条件入れます。

   onSubmit(e) {
        e.preventDefault();
        if(this.state.term){
            this.setState({
                term: '',
                items: [...this.state.items, this.state.term]
            });
        }
    }

これで間違えて押しても追加されません!

Todo Listの完成体はこちらです!

(はじめてCodepenを導入してみました!)

See the Pen Todo list made by React.js by manmanrai (@manmanrai) on CodePen.

Githubソースコードアップしました。
ディレクトリやファイルほぼデフォルトのままです。手入れたファイルはindex.jsのみになってます。

github.com